Update to 3.9.0

This commit is contained in:
DrKLO 2016-05-25 14:49:47 -07:00
parent 1c74ed4587
commit 85239ed7cf
174 changed files with 33705 additions and 16403 deletions

View file

@ -8,7 +8,7 @@ dependencies {
compile 'com.android.support:support-v4:23.3.0'
compile "com.google.android.gms:play-services-gcm:8.4.0"
compile "com.google.android.gms:play-services-maps:8.4.0"
compile 'net.hockeyapp.android:HockeySDK:3.6.+'
compile 'net.hockeyapp.android:HockeySDK:4.0.+'
compile 'com.googlecode.mp4parser:isoparser:1.0.+'
}
@ -63,7 +63,7 @@ android {
}
}
defaultConfig.versionCode = 787
defaultConfig.versionCode = 803
sourceSets.main {
jniLibs.srcDir 'libs'
@ -114,7 +114,7 @@ android {
defaultConfig {
minSdkVersion 9
targetSdkVersion 23
versionName "3.8.1"
versionName "3.9.0"
}
}

View file

@ -235,7 +235,7 @@ include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := tmessages.21
LOCAL_MODULE := tmessages.22
LOCAL_CFLAGS := -w -std=c11 -Os -DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64
LOCAL_CFLAGS += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DFIXED_POINT -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -fno-math-errno
LOCAL_CFLAGS += -DANDROID_NDK -DDISABLE_IMPORTGL -fno-strict-aliasing -fprefetch-loop-arrays -DAVOID_TABLES -DANDROID_TILE_BASED_DECODE -DANDROID_ARMV6_IDCT -ffast-math -D__STDC_CONSTANT_MACROS
@ -521,15 +521,12 @@ endif
LOCAL_SRC_FILES += \
./jni.c \
./sqlite_cursor.c \
./sqlite_database.c \
./sqlite_statement.c \
./sqlite.c \
./audio.c \
./utils.c \
./image.c \
./video.c \
./gifvideo.cpp \
./SqliteWrapper.cpp \
./TgNetWrapper.cpp \
./NativeLoader.cpp

View file

@ -0,0 +1,241 @@
#include "sqlite/sqlite3.h"
#include "tgnet/NativeByteBuffer.h"
#include "tgnet/BuffersStorage.h"
void throw_sqlite3_exception(JNIEnv *env, sqlite3 *handle, int errcode) {
if (SQLITE_OK == errcode) {
errcode = sqlite3_errcode(handle);
}
const char *errmsg = sqlite3_errmsg(handle);
jclass exClass = env->FindClass("org/telegram/SQLite/SQLiteException");
env->ThrowNew(exClass, errmsg);
}
extern "C" {
int Java_org_telegram_SQLite_SQLitePreparedStatement_step(JNIEnv *env, jobject object, int statementHandle) {
sqlite3_stmt *handle = (sqlite3_stmt *) statementHandle;
int errcode = sqlite3_step(handle);
if (errcode == SQLITE_ROW) {
return 0;
} else if(errcode == SQLITE_DONE) {
return 1;
} else if(errcode == SQLITE_BUSY) {
return -1;
}
throw_sqlite3_exception(env, sqlite3_db_handle(handle), errcode);
}
int Java_org_telegram_SQLite_SQLitePreparedStatement_prepare(JNIEnv *env, jobject object, int sqliteHandle, jstring sql) {
sqlite3 *handle = (sqlite3 *) sqliteHandle;
char const *sqlStr = env->GetStringUTFChars(sql, 0);
sqlite3_stmt *stmt_handle;
int errcode = sqlite3_prepare_v2(handle, sqlStr, -1, &stmt_handle, 0);
if (SQLITE_OK != errcode) {
throw_sqlite3_exception(env, handle, errcode);
}
if (sqlStr != 0) {
env->ReleaseStringUTFChars(sql, sqlStr);
}
return (int) stmt_handle;
}
void Java_org_telegram_SQLite_SQLitePreparedStatement_reset(JNIEnv *env, jobject object, int statementHandle) {
sqlite3_stmt *handle = (sqlite3_stmt *) statementHandle;
int errcode = sqlite3_reset(handle);
if (SQLITE_OK != errcode) {
throw_sqlite3_exception(env, sqlite3_db_handle(handle), errcode);
}
}
void Java_org_telegram_SQLite_SQLitePreparedStatement_finalize(JNIEnv *env, jobject object, int statementHandle) {
sqlite3_finalize((sqlite3_stmt *) statementHandle);
}
void Java_org_telegram_SQLite_SQLitePreparedStatement_bindByteBuffer(JNIEnv *env, jobject object, int statementHandle, int index, jobject value, int length) {
sqlite3_stmt *handle = (sqlite3_stmt *) statementHandle;
void *buf = env->GetDirectBufferAddress(value);
int errcode = sqlite3_bind_blob(handle, index, buf, length, SQLITE_STATIC);
if (SQLITE_OK != errcode) {
throw_sqlite3_exception(env, sqlite3_db_handle(handle), errcode);
}
}
void Java_org_telegram_SQLite_SQLitePreparedStatement_bindString(JNIEnv *env, jobject object, int statementHandle, int index, jstring value) {
sqlite3_stmt *handle = (sqlite3_stmt *) statementHandle;
char const *valueStr = env->GetStringUTFChars(value, 0);
int errcode = sqlite3_bind_text(handle, index, valueStr, -1, SQLITE_TRANSIENT);
if (SQLITE_OK != errcode) {
throw_sqlite3_exception(env, sqlite3_db_handle(handle), errcode);
}
if (valueStr != 0) {
env->ReleaseStringUTFChars(value, valueStr);
}
}
void Java_org_telegram_SQLite_SQLitePreparedStatement_bindInt(JNIEnv *env, jobject object, int statementHandle, int index, int value) {
sqlite3_stmt *handle = (sqlite3_stmt *) statementHandle;
int errcode = sqlite3_bind_int(handle, index, value);
if (SQLITE_OK != errcode) {
throw_sqlite3_exception(env, sqlite3_db_handle(handle), errcode);
}
}
void Java_org_telegram_SQLite_SQLitePreparedStatement_bindLong(JNIEnv *env, jobject object, int statementHandle, int index, long long value) {
sqlite3_stmt *handle = (sqlite3_stmt *) statementHandle;
int errcode = sqlite3_bind_int64(handle, index, value);
if (SQLITE_OK != errcode) {
throw_sqlite3_exception(env, sqlite3_db_handle(handle), errcode);
}
}
void Java_org_telegram_SQLite_SQLitePreparedStatement_bindDouble(JNIEnv *env, jobject object, int statementHandle, int index, double value) {
sqlite3_stmt *handle = (sqlite3_stmt *) statementHandle;
int errcode = sqlite3_bind_double(handle, index, value);
if (SQLITE_OK != errcode) {
throw_sqlite3_exception(env, sqlite3_db_handle(handle), errcode);
}
}
void Java_org_telegram_SQLite_SQLitePreparedStatement_bindNull(JNIEnv *env, jobject object, int statementHandle, int index) {
sqlite3_stmt *handle = (sqlite3_stmt *) statementHandle;
int errcode = sqlite3_bind_null(handle, index);
if (SQLITE_OK != errcode) {
throw_sqlite3_exception(env, sqlite3_db_handle(handle), errcode);
}
}
void Java_org_telegram_SQLite_SQLiteDatabase_closedb(JNIEnv *env, jobject object, int sqliteHandle) {
sqlite3 *handle = (sqlite3 *)sqliteHandle;
int err = sqlite3_close(handle);
if (SQLITE_OK != err) {
throw_sqlite3_exception(env, handle, err);
}
}
void Java_org_telegram_SQLite_SQLiteDatabase_beginTransaction(JNIEnv *env, jobject object, int sqliteHandle) {
sqlite3 *handle = (sqlite3 *)sqliteHandle;
sqlite3_exec(handle, "BEGIN", 0, 0, 0);
}
void Java_org_telegram_SQLite_SQLiteDatabase_commitTransaction(JNIEnv *env, jobject object, int sqliteHandle) {
sqlite3 *handle = (sqlite3 *)sqliteHandle;
sqlite3_exec(handle, "COMMIT", 0, 0, 0);
}
int Java_org_telegram_SQLite_SQLiteDatabase_opendb(JNIEnv *env, jobject object, jstring fileName, jstring tempDir) {
char const *fileNameStr = env->GetStringUTFChars(fileName, 0);
char const *tempDirStr = env->GetStringUTFChars(tempDir, 0);
if (sqlite3_temp_directory != 0) {
sqlite3_free(sqlite3_temp_directory);
}
sqlite3_temp_directory = sqlite3_mprintf("%s", tempDirStr);
sqlite3 *handle = 0;
int err = sqlite3_open(fileNameStr, &handle);
if (SQLITE_OK != err) {
throw_sqlite3_exception(env, handle, err);
}
if (fileNameStr != 0) {
env->ReleaseStringUTFChars(fileName, fileNameStr);
}
if (tempDirStr != 0) {
env->ReleaseStringUTFChars(tempDir, tempDirStr);
}
return (int)handle;
}
int Java_org_telegram_SQLite_SQLiteCursor_columnType(JNIEnv *env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
return sqlite3_column_type(handle, columnIndex);
}
int Java_org_telegram_SQLite_SQLiteCursor_columnIsNull(JNIEnv *env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
int valType = sqlite3_column_type(handle, columnIndex);
return SQLITE_NULL == valType;
}
int Java_org_telegram_SQLite_SQLiteCursor_columnIntValue(JNIEnv *env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
int valType = sqlite3_column_type(handle, columnIndex);
if (SQLITE_NULL == valType) {
return 0;
}
return sqlite3_column_int(handle, columnIndex);
}
long long Java_org_telegram_SQLite_SQLiteCursor_columnLongValue(JNIEnv *env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
int valType = sqlite3_column_type(handle, columnIndex);
if (SQLITE_NULL == valType) {
return 0;
}
return sqlite3_column_int64(handle, columnIndex);
}
double Java_org_telegram_SQLite_SQLiteCursor_columnDoubleValue(JNIEnv *env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
int valType = sqlite3_column_type(handle, columnIndex);
if (SQLITE_NULL == valType) {
return 0;
}
return sqlite3_column_double(handle, columnIndex);
}
jstring Java_org_telegram_SQLite_SQLiteCursor_columnStringValue(JNIEnv *env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
const char *str = (const char *) sqlite3_column_text(handle, columnIndex);
if (str != 0) {
return env->NewStringUTF(str);
}
return 0;
}
jbyteArray Java_org_telegram_SQLite_SQLiteCursor_columnByteArrayValue(JNIEnv *env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
const jbyte *buf = (const jbyte *) sqlite3_column_blob(handle, columnIndex);
int length = sqlite3_column_bytes(handle, columnIndex);
if (buf != nullptr && length > 0) {
jbyteArray result = env->NewByteArray(length);
env->SetByteArrayRegion(result, 0, length, buf);
return result;
}
return nullptr;
}
int Java_org_telegram_SQLite_SQLiteCursor_columnByteBufferValue(JNIEnv *env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *) statementHandle;
int length = sqlite3_column_bytes(handle, columnIndex);
if (length <= 0) {
return 0;
}
NativeByteBuffer *buffer = BuffersStorage::getInstance().getFreeBuffer(length);
if (buffer == nullptr) {
return 0;
}
const char *buf = (const char *) sqlite3_column_blob(handle, columnIndex);
if (buf == nullptr) {
return 0;
}
memcpy(buffer->bytes(), buf, length);
return (int) buffer;
}
}

View file

@ -7,7 +7,6 @@
#include <openssl/aes.h>
#include <unistd.h>
#include "utils.h"
#include "sqlite.h"
#include "image.h"
int registerNativeTgNetFunctions(JavaVM *vm, JNIEnv *env);
@ -21,10 +20,6 @@ jint JNI_OnLoad(JavaVM *vm, void *reserved) {
return -1;
}
if (sqliteOnJNILoad(vm, reserved, env) == -1) {
return -1;
}
if (imageOnJNILoad(vm, reserved, env) == -1) {
return -1;
}

View file

@ -22,6 +22,12 @@ extern "C" {
(defined(__i386__) && !defined(__SSE2__))
#define LIBYUV_DISABLE_X86
#endif
// MemorySanitizer does not support assembly code yet. http://crbug.com/344505
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
#define LIBYUV_DISABLE_X86
#endif
#endif
// Visual C 2012 required for AVX2.
#if defined(_M_IX86) && !defined(__clang__) && \
@ -36,7 +42,8 @@ extern "C" {
#endif // clang >= 3.4
#endif // __clang__
#if defined(_M_IX86) && (defined(VISUALC_HAS_AVX2) || defined(CLANG_HAS_AVX2))
#if !defined(LIBYUV_DISABLE_X86) && \
defined(_M_IX86) && (defined(VISUALC_HAS_AVX2) || defined(CLANG_HAS_AVX2))
#define HAS_HASHDJB2_AVX2
#endif

View file

@ -41,7 +41,7 @@ static const int kCpuHasAVX3 = 0x2000;
// These flags are only valid on MIPS processors.
static const int kCpuHasMIPS = 0x10000;
static const int kCpuHasMIPS_DSPR2 = 0x20000;
static const int kCpuHasDSPR2 = 0x20000;
// Internal function used to auto-init.
LIBYUV_API

View file

@ -384,12 +384,6 @@ int ARGBUnattenuate(const uint8* src_argb, int src_stride_argb,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
// Convert MJPG to ARGB.
LIBYUV_API
int MJPGToARGB(const uint8* sample, size_t sample_size,
uint8* argb, int argb_stride,
int w, int h, int dw, int dh);
// Internal function - do not call directly.
// Computes table of cumulative sum for image where the value is the sum
// of all values above and to the left of the entry. Used by ARGBBlur.
@ -453,6 +447,12 @@ int I420Interpolate(const uint8* src0_y, int src0_stride_y,
(defined(__i386__) && !defined(__SSE2__))
#define LIBYUV_DISABLE_X86
#endif
// MemorySanitizer does not support assembly code yet. http://crbug.com/344505
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
#define LIBYUV_DISABLE_X86
#endif
#endif
// The following are available on all x86 platforms:
#if !defined(LIBYUV_DISABLE_X86) && \
(defined(_M_IX86) || defined(__x86_64__) || defined(__i386__))

View file

@ -22,7 +22,12 @@ extern "C" {
(defined(__i386__) && !defined(__SSE2__))
#define LIBYUV_DISABLE_X86
#endif
// MemorySanitizer does not support assembly code yet. http://crbug.com/344505
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
#define LIBYUV_DISABLE_X86
#endif
#endif
// The following are available for Visual C and clangcl 32 bit:
#if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86)
#define HAS_TRANSPOSEWX8_SSSE3
@ -51,8 +56,8 @@ extern "C" {
#if !defined(LIBYUV_DISABLE_MIPS) && !defined(__native_client__) && \
defined(__mips__) && \
defined(__mips_dsp) && (__mips_dsp_rev >= 2)
#define HAS_TRANSPOSEWX8_MIPS_DSPR2
#define HAS_TRANSPOSEUVWX8_MIPS_DSPR2
#define HAS_TRANSPOSEWX8_DSPR2
#define HAS_TRANSPOSEUVWX8_DSPR2
#endif // defined(__mips__)
void TransposeWxH_C(const uint8* src, int src_stride,
@ -66,10 +71,10 @@ void TransposeWx8_SSSE3(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width);
void TransposeWx8_Fast_SSSE3(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width);
void TransposeWx8_MIPS_DSPR2(const uint8* src, int src_stride,
void TransposeWx8_DSPR2(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width);
void TransposeWx8_Fast_DSPR2(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width);
void TransposeWx8_Fast_MIPS_DSPR2(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width);
void TransposeWx8_Any_NEON(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width);
@ -77,8 +82,8 @@ void TransposeWx8_Any_SSSE3(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width);
void TransposeWx8_Fast_Any_SSSE3(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width);
void TransposeWx8_Any_MIPS_DSPR2(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width);
void TransposeWx8_Any_DSPR2(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width);
void TransposeUVWxH_C(const uint8* src, int src_stride,
uint8* dst_a, int dst_stride_a,
@ -94,9 +99,9 @@ void TransposeUVWx8_SSE2(const uint8* src, int src_stride,
void TransposeUVWx8_NEON(const uint8* src, int src_stride,
uint8* dst_a, int dst_stride_a,
uint8* dst_b, int dst_stride_b, int width);
void TransposeUVWx8_MIPS_DSPR2(const uint8* src, int src_stride,
uint8* dst_a, int dst_stride_a,
uint8* dst_b, int dst_stride_b, int width);
void TransposeUVWx8_DSPR2(const uint8* src, int src_stride,
uint8* dst_a, int dst_stride_a,
uint8* dst_b, int dst_stride_b, int width);
void TransposeUVWx8_Any_SSE2(const uint8* src, int src_stride,
uint8* dst_a, int dst_stride_a,
@ -104,9 +109,9 @@ void TransposeUVWx8_Any_SSE2(const uint8* src, int src_stride,
void TransposeUVWx8_Any_NEON(const uint8* src, int src_stride,
uint8* dst_a, int dst_stride_a,
uint8* dst_b, int dst_stride_b, int width);
void TransposeUVWx8_Any_MIPS_DSPR2(const uint8* src, int src_stride,
uint8* dst_a, int dst_stride_a,
uint8* dst_b, int dst_stride_b, int width);
void TransposeUVWx8_Any_DSPR2(const uint8* src, int src_stride,
uint8* dst_a, int dst_stride_a,
uint8* dst_b, int dst_stride_b, int width);
#ifdef __cplusplus
} // extern "C"

View file

@ -41,6 +41,12 @@ extern "C" {
(defined(__i386__) && !defined(__SSE2__))
#define LIBYUV_DISABLE_X86
#endif
// MemorySanitizer does not support assembly code yet. http://crbug.com/344505
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
#define LIBYUV_DISABLE_X86
#endif
#endif
// True if compiling for SSSE3 as a requirement.
#if defined(__SSSE3__) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 3))
#define LIBYUV_SSSE3_ONLY
@ -93,7 +99,6 @@ extern "C" {
#define HAS_ARGBTORGB24ROW_SSSE3
#define HAS_ARGBTORGB565DITHERROW_SSE2
#define HAS_ARGBTORGB565ROW_SSE2
#define HAS_ARGBTOUV422ROW_SSSE3
#define HAS_ARGBTOUV444ROW_SSSE3
#define HAS_ARGBTOUVJROW_SSSE3
#define HAS_ARGBTOUVROW_SSSE3
@ -105,17 +110,6 @@ extern "C" {
#define HAS_COPYROW_SSE2
#define HAS_H422TOARGBROW_SSSE3
#define HAS_I400TOARGBROW_SSE2
// The following functions fail on gcc/clang 32 bit with fpic and framepointer.
// caveat: clangcl uses row_win.cc which works.
#if defined(NDEBUG) || !(defined(_DEBUG) && defined(__i386__)) || \
!defined(__i386__) || defined(_MSC_VER)
// TODO(fbarchard): fix build error on x86 debug
// https://code.google.com/p/libyuv/issues/detail?id=524
#define HAS_I411TOARGBROW_SSSE3
// TODO(fbarchard): fix build error on android_full_debug=1
// https://code.google.com/p/libyuv/issues/detail?id=517
#define HAS_I422ALPHATOARGBROW_SSSE3
#endif
#define HAS_I422TOARGB1555ROW_SSSE3
#define HAS_I422TOARGB4444ROW_SSSE3
#define HAS_I422TOARGBROW_SSSE3
@ -129,7 +123,6 @@ extern "C" {
#define HAS_J422TOARGBROW_SSSE3
#define HAS_MERGEUVROW_SSE2
#define HAS_MIRRORROW_SSSE3
#define HAS_MIRRORROW_UV_SSSE3
#define HAS_MIRRORUVROW_SSSE3
#define HAS_NV12TOARGBROW_SSSE3
#define HAS_NV12TORGB565ROW_SSSE3
@ -173,6 +166,7 @@ extern "C" {
#define HAS_ARGBSHADEROW_SSE2
#define HAS_ARGBSUBTRACTROW_SSE2
#define HAS_ARGBUNATTENUATEROW_SSE2
#define HAS_BLENDPLANEROW_SSSE3
#define HAS_COMPUTECUMULATIVESUMROW_SSE2
#define HAS_CUMULATIVESUMTOAVERAGEROW_SSE2
#define HAS_INTERPOLATEROW_SSSE3
@ -182,7 +176,18 @@ extern "C" {
#define HAS_SOBELXROW_SSE2
#define HAS_SOBELXYROW_SSE2
#define HAS_SOBELYROW_SSE2
#define HAS_BLENDPLANEROW_SSSE3
// The following functions fail on gcc/clang 32 bit with fpic and framepointer.
// caveat: clangcl uses row_win.cc which works.
#if defined(NDEBUG) || !(defined(_DEBUG) && defined(__i386__)) || \
!defined(__i386__) || defined(_MSC_VER)
// TODO(fbarchard): fix build error on x86 debug
// https://code.google.com/p/libyuv/issues/detail?id=524
#define HAS_I411TOARGBROW_SSSE3
// TODO(fbarchard): fix build error on android_full_debug=1
// https://code.google.com/p/libyuv/issues/detail?id=517
#define HAS_I422ALPHATOARGBROW_SSSE3
#endif
#endif
// The following are available on all x86 platforms, but
@ -196,6 +201,7 @@ extern "C" {
#define HAS_ARGBPOLYNOMIALROW_AVX2
#define HAS_ARGBSHUFFLEROW_AVX2
#define HAS_ARGBTORGB565DITHERROW_AVX2
#define HAS_ARGBTOUVJROW_AVX2
#define HAS_ARGBTOUVROW_AVX2
#define HAS_ARGBTOYJROW_AVX2
#define HAS_ARGBTOYROW_AVX2
@ -207,15 +213,20 @@ extern "C" {
// https://code.google.com/p/libyuv/issues/detail?id=517
#define HAS_I422ALPHATOARGBROW_AVX2
#endif
#define HAS_I444TOARGBROW_AVX2
#define HAS_I411TOARGBROW_AVX2
#define HAS_I422TOARGB1555ROW_AVX2
#define HAS_I422TOARGB4444ROW_AVX2
#define HAS_I422TOARGBROW_AVX2
#define HAS_I422TORGB24ROW_AVX2
#define HAS_I422TORGB565ROW_AVX2
#define HAS_I422TORGBAROW_AVX2
#define HAS_I444TOARGBROW_AVX2
#define HAS_INTERPOLATEROW_AVX2
#define HAS_J422TOARGBROW_AVX2
#define HAS_MERGEUVROW_AVX2
#define HAS_MIRRORROW_AVX2
#define HAS_NV12TOARGBROW_AVX2
#define HAS_NV12TORGB565ROW_AVX2
#define HAS_NV21TOARGBROW_AVX2
#define HAS_SPLITUVROW_AVX2
#define HAS_UYVYTOARGBROW_AVX2
@ -245,12 +256,7 @@ extern "C" {
#define HAS_ARGBTOARGB1555ROW_AVX2
#define HAS_ARGBTOARGB4444ROW_AVX2
#define HAS_ARGBTORGB565ROW_AVX2
#define HAS_I411TOARGBROW_AVX2
#define HAS_I422TOARGB1555ROW_AVX2
#define HAS_I422TOARGB4444ROW_AVX2
#define HAS_I422TORGB565ROW_AVX2
#define HAS_J400TOARGBROW_AVX2
#define HAS_NV12TORGB565ROW_AVX2
#define HAS_RGB565TOARGBROW_AVX2
#endif
@ -264,7 +270,6 @@ extern "C" {
// The following are available on Neon platforms:
#if !defined(LIBYUV_DISABLE_NEON) && \
(defined(__aarch64__) || defined(__ARM_NEON__) || defined(LIBYUV_NEON))
#define HAS_I422ALPHATOARGBROW_NEON
#define HAS_ABGRTOUVROW_NEON
#define HAS_ABGRTOYROW_NEON
#define HAS_ARGB1555TOARGBROW_NEON
@ -281,7 +286,6 @@ extern "C" {
#define HAS_ARGBTORGB565DITHERROW_NEON
#define HAS_ARGBTORGB565ROW_NEON
#define HAS_ARGBTOUV411ROW_NEON
#define HAS_ARGBTOUV422ROW_NEON
#define HAS_ARGBTOUV444ROW_NEON
#define HAS_ARGBTOUVJROW_NEON
#define HAS_ARGBTOUVROW_NEON
@ -292,6 +296,7 @@ extern "C" {
#define HAS_COPYROW_NEON
#define HAS_I400TOARGBROW_NEON
#define HAS_I411TOARGBROW_NEON
#define HAS_I422ALPHATOARGBROW_NEON
#define HAS_I422TOARGB1555ROW_NEON
#define HAS_I422TOARGB4444ROW_NEON
#define HAS_I422TOARGBROW_NEON
@ -357,11 +362,11 @@ extern "C" {
(_MIPS_SIM == _MIPS_SIM_ABI32) && (__mips_isa_rev < 6)
#define HAS_COPYROW_MIPS
#if defined(__mips_dsp) && (__mips_dsp_rev >= 2)
#define HAS_I422TOARGBROW_MIPS_DSPR2
#define HAS_INTERPOLATEROW_MIPS_DSPR2
#define HAS_MIRRORROW_MIPS_DSPR2
#define HAS_MIRRORUVROW_MIPS_DSPR2
#define HAS_SPLITUVROW_MIPS_DSPR2
#define HAS_I422TOARGBROW_DSPR2
#define HAS_INTERPOLATEROW_DSPR2
#define HAS_MIRRORROW_DSPR2
#define HAS_MIRRORUVROW_DSPR2
#define HAS_SPLITUVROW_DSPR2
#endif
#endif
@ -648,8 +653,6 @@ void ARGBToYRow_NEON(const uint8* src_argb, uint8* dst_y, int width);
void ARGBToYJRow_NEON(const uint8* src_argb, uint8* dst_y, int width);
void ARGBToUV444Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
int width);
void ARGBToUV422Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
int width);
void ARGBToUV411Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
int width);
void ARGBToUVRow_NEON(const uint8* src_argb, int src_stride_argb,
@ -712,8 +715,8 @@ void ARGB4444ToYRow_Any_NEON(const uint8* src_argb4444, uint8* dst_y,
void ARGBToUVRow_AVX2(const uint8* src_argb, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width);
void ARGBToUVRow_Any_AVX2(const uint8* src_argb, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width);
void ARGBToUVJRow_AVX2(const uint8* src_argb, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width);
void ARGBToUVRow_SSSE3(const uint8* src_argb, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width);
void ARGBToUVJRow_SSSE3(const uint8* src_argb, int src_stride_argb,
@ -724,6 +727,10 @@ void ABGRToUVRow_SSSE3(const uint8* src_abgr, int src_stride_abgr,
uint8* dst_u, uint8* dst_v, int width);
void RGBAToUVRow_SSSE3(const uint8* src_rgba, int src_stride_rgba,
uint8* dst_u, uint8* dst_v, int width);
void ARGBToUVRow_Any_AVX2(const uint8* src_argb, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width);
void ARGBToUVJRow_Any_AVX2(const uint8* src_argb, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width);
void ARGBToUVRow_Any_SSSE3(const uint8* src_argb, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width);
void ARGBToUVJRow_Any_SSSE3(const uint8* src_argb, int src_stride_argb,
@ -736,8 +743,6 @@ void RGBAToUVRow_Any_SSSE3(const uint8* src_rgba, int src_stride_rgba,
uint8* dst_u, uint8* dst_v, int width);
void ARGBToUV444Row_Any_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
int width);
void ARGBToUV422Row_Any_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
int width);
void ARGBToUV411Row_Any_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
int width);
void ARGBToUVRow_Any_NEON(const uint8* src_argb, int src_stride_argb,
@ -788,24 +793,15 @@ void ARGBToUV444Row_SSSE3(const uint8* src_argb,
void ARGBToUV444Row_Any_SSSE3(const uint8* src_argb,
uint8* dst_u, uint8* dst_v, int width);
void ARGBToUV422Row_SSSE3(const uint8* src_argb,
uint8* dst_u, uint8* dst_v, int width);
void ARGBToUV422Row_Any_SSSE3(const uint8* src_argb,
uint8* dst_u, uint8* dst_v, int width);
void ARGBToUV444Row_C(const uint8* src_argb,
uint8* dst_u, uint8* dst_v, int width);
void ARGBToUV422Row_C(const uint8* src_argb,
uint8* dst_u, uint8* dst_v, int width);
void ARGBToUV411Row_C(const uint8* src_argb,
uint8* dst_u, uint8* dst_v, int width);
void ARGBToUVJ422Row_C(const uint8* src_argb,
uint8* dst_u, uint8* dst_v, int width);
void MirrorRow_AVX2(const uint8* src, uint8* dst, int width);
void MirrorRow_SSSE3(const uint8* src, uint8* dst, int width);
void MirrorRow_NEON(const uint8* src, uint8* dst, int width);
void MirrorRow_MIPS_DSPR2(const uint8* src, uint8* dst, int width);
void MirrorRow_DSPR2(const uint8* src, uint8* dst, int width);
void MirrorRow_C(const uint8* src, uint8* dst, int width);
void MirrorRow_Any_AVX2(const uint8* src, uint8* dst, int width);
void MirrorRow_Any_SSSE3(const uint8* src, uint8* dst, int width);
@ -816,10 +812,9 @@ void MirrorUVRow_SSSE3(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width);
void MirrorUVRow_NEON(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width);
void MirrorUVRow_MIPS_DSPR2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width);
void MirrorUVRow_C(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width);
void MirrorUVRow_DSPR2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width);
void MirrorUVRow_C(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int width);
void ARGBMirrorRow_AVX2(const uint8* src, uint8* dst, int width);
void ARGBMirrorRow_SSE2(const uint8* src, uint8* dst, int width);
@ -836,16 +831,16 @@ void SplitUVRow_AVX2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width);
void SplitUVRow_NEON(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width);
void SplitUVRow_MIPS_DSPR2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width);
void SplitUVRow_DSPR2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width);
void SplitUVRow_Any_SSE2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width);
void SplitUVRow_Any_AVX2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width);
void SplitUVRow_Any_NEON(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width);
void SplitUVRow_Any_MIPS_DSPR2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width);
void SplitUVRow_Any_DSPR2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width);
void MergeUVRow_C(const uint8* src_u, const uint8* src_v, uint8* dst_uv,
int width);
@ -1625,18 +1620,18 @@ void UYVYToARGBRow_Any_NEON(const uint8* src_uyvy,
uint8* dst_argb,
const struct YuvConstants* yuvconstants,
int width);
void I422ToARGBRow_MIPS_DSPR2(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
uint8* dst_argb,
const struct YuvConstants* yuvconstants,
int width);
void I422ToARGBRow_MIPS_DSPR2(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
uint8* dst_argb,
const struct YuvConstants* yuvconstants,
int width);
void I422ToARGBRow_DSPR2(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
uint8* dst_argb,
const struct YuvConstants* yuvconstants,
int width);
void I422ToARGBRow_DSPR2(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
uint8* dst_argb,
const struct YuvConstants* yuvconstants,
int width);
void YUY2ToYRow_AVX2(const uint8* src_yuy2, uint8* dst_y, int width);
void YUY2ToUVRow_AVX2(const uint8* src_yuy2, int stride_yuy2,
@ -1846,9 +1841,9 @@ void InterpolateRow_AVX2(uint8* dst_ptr, const uint8* src_ptr,
void InterpolateRow_NEON(uint8* dst_ptr, const uint8* src_ptr,
ptrdiff_t src_stride_ptr, int width,
int source_y_fraction);
void InterpolateRow_MIPS_DSPR2(uint8* dst_ptr, const uint8* src_ptr,
ptrdiff_t src_stride_ptr, int width,
int source_y_fraction);
void InterpolateRow_DSPR2(uint8* dst_ptr, const uint8* src_ptr,
ptrdiff_t src_stride_ptr, int width,
int source_y_fraction);
void InterpolateRow_Any_NEON(uint8* dst_ptr, const uint8* src_ptr,
ptrdiff_t src_stride_ptr, int width,
int source_y_fraction);
@ -1858,9 +1853,9 @@ void InterpolateRow_Any_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
void InterpolateRow_Any_AVX2(uint8* dst_ptr, const uint8* src_ptr,
ptrdiff_t src_stride_ptr, int width,
int source_y_fraction);
void InterpolateRow_Any_MIPS_DSPR2(uint8* dst_ptr, const uint8* src_ptr,
ptrdiff_t src_stride_ptr, int width,
int source_y_fraction);
void InterpolateRow_Any_DSPR2(uint8* dst_ptr, const uint8* src_ptr,
ptrdiff_t src_stride_ptr, int width,
int source_y_fraction);
void InterpolateRow_16_C(uint16* dst_ptr, const uint16* src_ptr,
ptrdiff_t src_stride_ptr,

View file

@ -23,6 +23,12 @@ extern "C" {
(defined(__i386__) && !defined(__SSE2__))
#define LIBYUV_DISABLE_X86
#endif
// MemorySanitizer does not support assembly code yet. http://crbug.com/344505
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
#define LIBYUV_DISABLE_X86
#endif
#endif
// GCC >= 4.7.0 required for AVX2.
#if defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))
@ -90,10 +96,10 @@ extern "C" {
// The following are available on Mips platforms:
#if !defined(LIBYUV_DISABLE_MIPS) && !defined(__native_client__) && \
defined(__mips__) && defined(__mips_dsp) && (__mips_dsp_rev >= 2)
#define HAS_SCALEROWDOWN2_MIPS_DSPR2
#define HAS_SCALEROWDOWN4_MIPS_DSPR2
#define HAS_SCALEROWDOWN34_MIPS_DSPR2
#define HAS_SCALEROWDOWN38_MIPS_DSPR2
#define HAS_SCALEROWDOWN2_DSPR2
#define HAS_SCALEROWDOWN4_DSPR2
#define HAS_SCALEROWDOWN34_DSPR2
#define HAS_SCALEROWDOWN38_DSPR2
#endif
// Scale ARGB vertically with bilinear interpolation.
@ -146,6 +152,8 @@ void ScaleRowDown2Linear_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
uint16* dst, int dst_width);
void ScaleRowDown2Box_C(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width);
void ScaleRowDown2Box_Odd_C(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width);
void ScaleRowDown2Box_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
uint16* dst, int dst_width);
void ScaleRowDown4_C(const uint8* src_ptr, ptrdiff_t src_stride,
@ -269,13 +277,17 @@ void ScaleRowDown2_Any_SSSE3(const uint8* src_ptr, ptrdiff_t src_stride,
void ScaleRowDown2Linear_Any_SSSE3(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst_ptr, int dst_width);
void ScaleRowDown2Box_Any_SSSE3(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst_ptr, int dst_width);
uint8* dst_ptr, int dst_width);
void ScaleRowDown2Box_Odd_SSSE3(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst_ptr, int dst_width);
void ScaleRowDown2_Any_AVX2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst_ptr, int dst_width);
void ScaleRowDown2Linear_Any_AVX2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst_ptr, int dst_width);
void ScaleRowDown2Box_Any_AVX2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst_ptr, int dst_width);
uint8* dst_ptr, int dst_width);
void ScaleRowDown2Box_Odd_AVX2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst_ptr, int dst_width);
void ScaleRowDown4_Any_SSSE3(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst_ptr, int dst_width);
void ScaleRowDown4Box_Any_SSSE3(const uint8* src_ptr, ptrdiff_t src_stride,
@ -431,6 +443,8 @@ void ScaleRowDown2Linear_Any_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width);
void ScaleRowDown2Box_Any_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width);
void ScaleRowDown2Box_Odd_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width);
void ScaleRowDown4_Any_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst_ptr, int dst_width);
void ScaleRowDown4Box_Any_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
@ -460,28 +474,26 @@ void ScaleFilterCols_NEON(uint8* dst_ptr, const uint8* src_ptr,
void ScaleFilterCols_Any_NEON(uint8* dst_ptr, const uint8* src_ptr,
int dst_width, int x, int dx);
void ScaleRowDown2_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width);
void ScaleRowDown2Box_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width);
void ScaleRowDown4_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width);
void ScaleRowDown4Box_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width);
void ScaleRowDown34_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width);
void ScaleRowDown34_0_Box_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* d, int dst_width);
void ScaleRowDown34_1_Box_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* d, int dst_width);
void ScaleRowDown38_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width);
void ScaleRowDown38_2_Box_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst_ptr, int dst_width);
void ScaleRowDown38_3_Box_MIPS_DSPR2(const uint8* src_ptr,
ptrdiff_t src_stride,
uint8* dst_ptr, int dst_width);
void ScaleRowDown2_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width);
void ScaleRowDown2Box_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width);
void ScaleRowDown4_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width);
void ScaleRowDown4Box_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width);
void ScaleRowDown34_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width);
void ScaleRowDown34_0_Box_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* d, int dst_width);
void ScaleRowDown34_1_Box_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* d, int dst_width);
void ScaleRowDown38_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width);
void ScaleRowDown38_2_Box_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst_ptr, int dst_width);
void ScaleRowDown38_3_Box_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst_ptr, int dst_width);
#ifdef __cplusplus
} // extern "C"

View file

@ -11,6 +11,6 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT
#define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 1561
#define LIBYUV_VERSION 1586
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT

View file

@ -303,14 +303,14 @@ static int X420ToI420(const uint8* src_y,
}
}
#endif
#if defined(HAS_SPLITUVROW_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) &&
#if defined(HAS_SPLITUVROW_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) &&
IS_ALIGNED(src_uv, 4) && IS_ALIGNED(src_stride_uv, 4) &&
IS_ALIGNED(dst_u, 4) && IS_ALIGNED(dst_stride_u, 4) &&
IS_ALIGNED(dst_v, 4) && IS_ALIGNED(dst_stride_v, 4)) {
SplitUVRow = SplitUVRow_Any_MIPS_DSPR2;
SplitUVRow = SplitUVRow_Any_DSPR2;
if (IS_ALIGNED(halfwidth, 16)) {
SplitUVRow = SplitUVRow_MIPS_DSPR2;
SplitUVRow = SplitUVRow_DSPR2;
}
}
#endif

View file

@ -92,13 +92,13 @@ static int I420ToARGBMatrix(const uint8* src_y, int src_stride_y,
}
}
#endif
#if defined(HAS_I422TOARGBROW_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(width, 4) &&
#if defined(HAS_I422TOARGBROW_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(width, 4) &&
IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) &&
IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) &&
IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) &&
IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) {
I422ToARGBRow = I422ToARGBRow_MIPS_DSPR2;
I422ToARGBRow = I422ToARGBRow_DSPR2;
}
#endif
@ -262,13 +262,13 @@ static int I422ToARGBMatrix(const uint8* src_y, int src_stride_y,
}
}
#endif
#if defined(HAS_I422TOARGBROW_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(width, 4) &&
#if defined(HAS_I422TOARGBROW_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(width, 4) &&
IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) &&
IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) &&
IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) &&
IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) {
I422ToARGBRow = I422ToARGBRow_MIPS_DSPR2;
I422ToARGBRow = I422ToARGBRow_DSPR2;
}
#endif
@ -607,13 +607,13 @@ static int I420AlphaToARGBMatrix(const uint8* src_y, int src_stride_y,
}
}
#endif
#if defined(HAS_I422ALPHATOARGBROW_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(width, 4) &&
#if defined(HAS_I422ALPHATOARGBROW_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(width, 4) &&
IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) &&
IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) &&
IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) &&
IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) {
I422AlphaToARGBRow = I422AlphaToARGBRow_MIPS_DSPR2;
I422AlphaToARGBRow = I422AlphaToARGBRow_DSPR2;
}
#endif
#if defined(HAS_ARGBATTENUATEROW_SSSE3)

View file

@ -445,7 +445,7 @@ int I420ToNV21(const uint8* src_y, int src_stride_y,
return I420ToNV12(src_y, src_stride_y,
src_v, src_stride_v,
src_u, src_stride_u,
dst_y, src_stride_y,
dst_y, dst_stride_y,
dst_vu, dst_stride_vu,
width, height);
}
@ -498,13 +498,13 @@ static int I420ToRGBAMatrix(const uint8* src_y, int src_stride_y,
}
}
#endif
#if defined(HAS_I422TORGBAROW_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(width, 4) &&
#if defined(HAS_I422TORGBAROW_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(width, 4) &&
IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) &&
IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) &&
IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) &&
IS_ALIGNED(dst_rgba, 4) && IS_ALIGNED(dst_stride_rgba, 4)) {
I422ToRGBARow = I422ToRGBARow_MIPS_DSPR2;
I422ToRGBARow = I422ToRGBARow_DSPR2;
}
#endif
@ -888,12 +888,12 @@ int I420ToRGB565Dither(const uint8* src_y, int src_stride_y,
}
}
#endif
#if defined(HAS_I422TOARGBROW_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(width, 4) &&
#if defined(HAS_I422TOARGBROW_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(width, 4) &&
IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) &&
IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) &&
IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2)) {
I422ToARGBRow = I422ToARGBRow_MIPS_DSPR2;
I422ToARGBRow = I422ToARGBRow_DSPR2;
}
#endif
#if defined(HAS_ARGBTORGB565DITHERROW_SSE2)

View file

@ -109,13 +109,16 @@ int ARGBToI422(const uint8* src_argb, int src_stride_argb,
uint8* dst_v, int dst_stride_v,
int width, int height) {
int y;
void (*ARGBToUV422Row)(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
int width) = ARGBToUV422Row_C;
void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C;
void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int width) =
ARGBToYRow_C;
if (!src_argb || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) {
if (!src_argb ||
!dst_y || !dst_u || !dst_v ||
width <= 0 || height == 0) {
return -1;
}
// Negative height means invert the image.
if (height < 0) {
height = -height;
src_argb = src_argb + (height - 1) * src_stride_argb;
@ -130,34 +133,22 @@ int ARGBToI422(const uint8* src_argb, int src_stride_argb,
height = 1;
src_stride_argb = dst_stride_y = dst_stride_u = dst_stride_v = 0;
}
#if defined(HAS_ARGBTOUV422ROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) {
ARGBToUV422Row = ARGBToUV422Row_Any_SSSE3;
if (IS_ALIGNED(width, 16)) {
ARGBToUV422Row = ARGBToUV422Row_SSSE3;
}
}
#endif
#if defined(HAS_ARGBTOUV422ROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
ARGBToUV422Row = ARGBToUV422Row_Any_NEON;
if (IS_ALIGNED(width, 16)) {
ARGBToUV422Row = ARGBToUV422Row_NEON;
}
}
#endif
#if defined(HAS_ARGBTOYROW_SSSE3)
#if defined(HAS_ARGBTOYROW_SSSE3) && defined(HAS_ARGBTOUVROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) {
ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
ARGBToYRow = ARGBToYRow_Any_SSSE3;
if (IS_ALIGNED(width, 16)) {
ARGBToUVRow = ARGBToUVRow_SSSE3;
ARGBToYRow = ARGBToYRow_SSSE3;
}
}
#endif
#if defined(HAS_ARGBTOYROW_AVX2)
#if defined(HAS_ARGBTOYROW_AVX2) && defined(HAS_ARGBTOUVROW_AVX2)
if (TestCpuFlag(kCpuHasAVX2)) {
ARGBToUVRow = ARGBToUVRow_Any_AVX2;
ARGBToYRow = ARGBToYRow_Any_AVX2;
if (IS_ALIGNED(width, 32)) {
ARGBToUVRow = ARGBToUVRow_AVX2;
ARGBToYRow = ARGBToYRow_AVX2;
}
}
@ -170,9 +161,17 @@ int ARGBToI422(const uint8* src_argb, int src_stride_argb,
}
}
#endif
#if defined(HAS_ARGBTOUVROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
ARGBToUVRow = ARGBToUVRow_Any_NEON;
if (IS_ALIGNED(width, 16)) {
ARGBToUVRow = ARGBToUVRow_NEON;
}
}
#endif
for (y = 0; y < height; ++y) {
ARGBToUV422Row(src_argb, dst_u, dst_v, width);
ARGBToUVRow(src_argb, 0, dst_u, dst_v, width);
ARGBToYRow(src_argb, dst_y, width);
src_argb += src_stride_argb;
dst_y += dst_stride_y;
@ -478,8 +477,8 @@ int ARGBToYUY2(const uint8* src_argb, int src_stride_argb,
uint8* dst_yuy2, int dst_stride_yuy2,
int width, int height) {
int y;
void (*ARGBToUV422Row)(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
int width) = ARGBToUV422Row_C;
void (*ARGBToUVRow)(const uint8* src_argb, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C;
void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int width) =
ARGBToYRow_C;
void (*I422ToYUY2Row)(const uint8* src_y, const uint8* src_u,
@ -502,34 +501,22 @@ int ARGBToYUY2(const uint8* src_argb, int src_stride_argb,
height = 1;
src_stride_argb = dst_stride_yuy2 = 0;
}
#if defined(HAS_ARGBTOUV422ROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) {
ARGBToUV422Row = ARGBToUV422Row_Any_SSSE3;
if (IS_ALIGNED(width, 16)) {
ARGBToUV422Row = ARGBToUV422Row_SSSE3;
}
}
#endif
#if defined(HAS_ARGBTOUV422ROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
ARGBToUV422Row = ARGBToUV422Row_Any_NEON;
if (IS_ALIGNED(width, 16)) {
ARGBToUV422Row = ARGBToUV422Row_NEON;
}
}
#endif
#if defined(HAS_ARGBTOYROW_SSSE3)
#if defined(HAS_ARGBTOYROW_SSSE3) && defined(HAS_ARGBTOUVROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) {
ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
ARGBToYRow = ARGBToYRow_Any_SSSE3;
if (IS_ALIGNED(width, 16)) {
ARGBToUVRow = ARGBToUVRow_SSSE3;
ARGBToYRow = ARGBToYRow_SSSE3;
}
}
#endif
#if defined(HAS_ARGBTOYROW_AVX2)
#if defined(HAS_ARGBTOYROW_AVX2) && defined(HAS_ARGBTOUVROW_AVX2)
if (TestCpuFlag(kCpuHasAVX2)) {
ARGBToUVRow = ARGBToUVRow_Any_AVX2;
ARGBToYRow = ARGBToYRow_Any_AVX2;
if (IS_ALIGNED(width, 32)) {
ARGBToUVRow = ARGBToUVRow_AVX2;
ARGBToYRow = ARGBToYRow_AVX2;
}
}
@ -542,7 +529,14 @@ int ARGBToYUY2(const uint8* src_argb, int src_stride_argb,
}
}
#endif
#if defined(HAS_ARGBTOUVROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
ARGBToUVRow = ARGBToUVRow_Any_NEON;
if (IS_ALIGNED(width, 16)) {
ARGBToUVRow = ARGBToUVRow_NEON;
}
}
#endif
#if defined(HAS_I422TOYUY2ROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
I422ToYUY2Row = I422ToYUY2Row_Any_SSE2;
@ -567,7 +561,7 @@ int ARGBToYUY2(const uint8* src_argb, int src_stride_argb,
uint8* row_v = row_u + ((width + 63) & ~63) / 2;
for (y = 0; y < height; ++y) {
ARGBToUV422Row(src_argb, row_u, row_v, width);
ARGBToUVRow(src_argb, 0, row_u, row_v, width);
ARGBToYRow(src_argb, row_y, width);
I422ToYUY2Row(row_y, row_u, row_v, dst_yuy2, width);
src_argb += src_stride_argb;
@ -585,8 +579,8 @@ int ARGBToUYVY(const uint8* src_argb, int src_stride_argb,
uint8* dst_uyvy, int dst_stride_uyvy,
int width, int height) {
int y;
void (*ARGBToUV422Row)(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
int width) = ARGBToUV422Row_C;
void (*ARGBToUVRow)(const uint8* src_argb, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C;
void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int width) =
ARGBToYRow_C;
void (*I422ToUYVYRow)(const uint8* src_y, const uint8* src_u,
@ -609,34 +603,22 @@ int ARGBToUYVY(const uint8* src_argb, int src_stride_argb,
height = 1;
src_stride_argb = dst_stride_uyvy = 0;
}
#if defined(HAS_ARGBTOUV422ROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) {
ARGBToUV422Row = ARGBToUV422Row_Any_SSSE3;
if (IS_ALIGNED(width, 16)) {
ARGBToUV422Row = ARGBToUV422Row_SSSE3;
}
}
#endif
#if defined(HAS_ARGBTOUV422ROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
ARGBToUV422Row = ARGBToUV422Row_Any_NEON;
if (IS_ALIGNED(width, 16)) {
ARGBToUV422Row = ARGBToUV422Row_NEON;
}
}
#endif
#if defined(HAS_ARGBTOYROW_SSSE3)
#if defined(HAS_ARGBTOYROW_SSSE3) && defined(HAS_ARGBTOUVROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) {
ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
ARGBToYRow = ARGBToYRow_Any_SSSE3;
if (IS_ALIGNED(width, 16)) {
ARGBToUVRow = ARGBToUVRow_SSSE3;
ARGBToYRow = ARGBToYRow_SSSE3;
}
}
#endif
#if defined(HAS_ARGBTOYROW_AVX2)
#if defined(HAS_ARGBTOYROW_AVX2) && defined(HAS_ARGBTOUVROW_AVX2)
if (TestCpuFlag(kCpuHasAVX2)) {
ARGBToUVRow = ARGBToUVRow_Any_AVX2;
ARGBToYRow = ARGBToYRow_Any_AVX2;
if (IS_ALIGNED(width, 32)) {
ARGBToUVRow = ARGBToUVRow_AVX2;
ARGBToYRow = ARGBToYRow_AVX2;
}
}
@ -649,7 +631,14 @@ int ARGBToUYVY(const uint8* src_argb, int src_stride_argb,
}
}
#endif
#if defined(HAS_ARGBTOUVROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
ARGBToUVRow = ARGBToUVRow_Any_NEON;
if (IS_ALIGNED(width, 16)) {
ARGBToUVRow = ARGBToUVRow_NEON;
}
}
#endif
#if defined(HAS_I422TOUYVYROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
I422ToUYVYRow = I422ToUYVYRow_Any_SSE2;
@ -674,7 +663,7 @@ int ARGBToUYVY(const uint8* src_argb, int src_stride_argb,
uint8* row_v = row_u + ((width + 63) & ~63) / 2;
for (y = 0; y < height; ++y) {
ARGBToUV422Row(src_argb, row_u, row_v, width);
ARGBToUVRow(src_argb, 0, row_u, row_v, width);
ARGBToYRow(src_argb, row_y, width);
I422ToUYVYRow(row_y, row_u, row_v, dst_uyvy, width);
src_argb += src_stride_argb;
@ -1157,21 +1146,24 @@ int ARGBToJ420(const uint8* src_argb, int src_stride_argb,
return 0;
}
// ARGB little endian (bgra in memory) to J422
// Convert ARGB to J422. (JPeg full range I422).
LIBYUV_API
int ARGBToJ422(const uint8* src_argb, int src_stride_argb,
uint8* dst_y, int dst_stride_y,
uint8* dst_yj, int dst_stride_yj,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height) {
int y;
void (*ARGBToUVJ422Row)(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
int width) = ARGBToUVJ422Row_C;
void (*ARGBToYJRow)(const uint8* src_argb, uint8* dst_y, int width) =
void (*ARGBToUVJRow)(const uint8* src_argb0, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width) = ARGBToUVJRow_C;
void (*ARGBToYJRow)(const uint8* src_argb, uint8* dst_yj, int width) =
ARGBToYJRow_C;
if (!src_argb || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) {
if (!src_argb ||
!dst_yj || !dst_u || !dst_v ||
width <= 0 || height == 0) {
return -1;
}
// Negative height means invert the image.
if (height < 0) {
height = -height;
src_argb = src_argb + (height - 1) * src_stride_argb;
@ -1179,34 +1171,19 @@ int ARGBToJ422(const uint8* src_argb, int src_stride_argb,
}
// Coalesce rows.
if (src_stride_argb == width * 4 &&
dst_stride_y == width &&
dst_stride_yj == width &&
dst_stride_u * 2 == width &&
dst_stride_v * 2 == width) {
width *= height;
height = 1;
src_stride_argb = dst_stride_y = dst_stride_u = dst_stride_v = 0;
src_stride_argb = dst_stride_yj = dst_stride_u = dst_stride_v = 0;
}
#if defined(HAS_ARGBTOUVJ422ROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) {
ARGBToUVJ422Row = ARGBToUVJ422Row_Any_SSSE3;
if (IS_ALIGNED(width, 16)) {
ARGBToUVJ422Row = ARGBToUVJ422Row_SSSE3;
}
}
#endif
#if defined(HAS_ARGBTOUVJ422ROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
ARGBToUVJ422Row = ARGBToUVJ422Row_Any_NEON;
if (IS_ALIGNED(width, 16)) {
ARGBToUVJ422Row = ARGBToUVJ422Row_NEON;
}
}
#endif
#if defined(HAS_ARGBTOYJROW_SSSE3)
#if defined(HAS_ARGBTOYJROW_SSSE3) && defined(HAS_ARGBTOUVJROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) {
ARGBToUVJRow = ARGBToUVJRow_Any_SSSE3;
ARGBToYJRow = ARGBToYJRow_Any_SSSE3;
if (IS_ALIGNED(width, 16)) {
ARGBToUVJRow = ARGBToUVJRow_SSSE3;
ARGBToYJRow = ARGBToYJRow_SSSE3;
}
}
@ -1227,12 +1204,20 @@ int ARGBToJ422(const uint8* src_argb, int src_stride_argb,
}
}
#endif
#if defined(HAS_ARGBTOUVJROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
ARGBToUVJRow = ARGBToUVJRow_Any_NEON;
if (IS_ALIGNED(width, 16)) {
ARGBToUVJRow = ARGBToUVJRow_NEON;
}
}
#endif
for (y = 0; y < height; ++y) {
ARGBToUVJ422Row(src_argb, dst_u, dst_v, width);
ARGBToYJRow(src_argb, dst_y, width);
ARGBToUVJRow(src_argb, 0, dst_u, dst_v, width);
ARGBToYJRow(src_argb, dst_yj, width);
src_argb += src_stride_argb;
dst_y += dst_stride_y;
dst_yj += dst_stride_yj;
dst_u += dst_stride_u;
dst_v += dst_stride_v;
}

View file

@ -23,7 +23,7 @@ namespace libyuv {
extern "C" {
#endif
// Convert camera sample to I420 with cropping, rotation and vertical flip.
// Convert camera sample to ARGB with cropping, rotation and vertical flip.
// src_width is used for source stride computation
// src_height is used to compute location of planes, and indicate inversion
// sample_size is measured in bytes and is the size of the frame.
@ -51,8 +51,8 @@ int ConvertToARGB(const uint8* sample, size_t sample_size,
// also enable temporary buffer.
LIBYUV_BOOL need_buf = (rotation && format != FOURCC_ARGB) ||
crop_argb == sample;
uint8* tmp_argb = crop_argb;
int tmp_argb_stride = argb_stride;
uint8* dest_argb = crop_argb;
int dest_argb_stride = argb_stride;
uint8* rotate_buffer = NULL;
int abs_crop_height = (crop_height < 0) ? -crop_height : crop_height;
@ -66,13 +66,13 @@ int ConvertToARGB(const uint8* sample, size_t sample_size,
}
if (need_buf) {
int argb_size = crop_width * abs_crop_height * 4;
int argb_size = crop_width * 4 * abs_crop_height;
rotate_buffer = (uint8*)malloc(argb_size);
if (!rotate_buffer) {
return 1; // Out of memory runtime error.
}
crop_argb = rotate_buffer;
argb_stride = crop_width;
argb_stride = crop_width * 4;
}
switch (format) {
@ -291,7 +291,7 @@ int ConvertToARGB(const uint8* sample, size_t sample_size,
if (need_buf) {
if (!r) {
r = ARGBRotate(crop_argb, argb_stride,
tmp_argb, tmp_argb_stride,
dest_argb, dest_argb_stride,
crop_width, abs_crop_height, rotation);
}
free(rotate_buffer);

View file

@ -10,12 +10,12 @@
#include "libyuv/cpu_id.h"
#if defined(_MSC_VER) && !defined(__clang__)
#if defined(_MSC_VER)
#include <intrin.h> // For __cpuidex()
#endif
#if !defined(__pnacl__) && !defined(__CLR_VER) && \
!defined(__native_client__) && (defined(_M_IX86) || defined(_M_X64)) && \
defined(_MSC_VER) && !defined(__clang__) && (_MSC_FULL_VER >= 160040219)
defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 160040219)
#include <immintrin.h> // For _xgetbv()
#endif
@ -36,7 +36,8 @@ extern "C" {
// For functions that use the stack and have runtime checks for overflow,
// use SAFEBUFFERS to avoid additional check.
#if (defined(_MSC_VER) && !defined(__clang__)) && (_MSC_FULL_VER >= 160040219)
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 160040219) && \
!defined(__clang__)
#define SAFEBUFFERS __declspec(safebuffers)
#else
#define SAFEBUFFERS
@ -48,9 +49,9 @@ extern "C" {
!defined(__pnacl__) && !defined(__CLR_VER)
LIBYUV_API
void CpuId(uint32 info_eax, uint32 info_ecx, uint32* cpu_info) {
#if defined(_MSC_VER) && !defined(__clang__)
#if defined(_MSC_VER)
// Visual C version uses intrinsic or inline x86 assembly.
#if (_MSC_FULL_VER >= 160040219)
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 160040219)
__cpuidex((int*)(cpu_info), info_eax, info_ecx);
#elif defined(_M_IX86)
__asm {
@ -71,7 +72,7 @@ void CpuId(uint32 info_eax, uint32 info_ecx, uint32* cpu_info) {
}
#endif
// GCC version uses inline x86 assembly.
#else // defined(_MSC_VER) && !defined(__clang__)
#else // defined(_MSC_VER)
uint32 info_ebx, info_edx;
asm volatile (
#if defined( __i386__) && defined(__PIC__)
@ -89,7 +90,7 @@ void CpuId(uint32 info_eax, uint32 info_ecx, uint32* cpu_info) {
cpu_info[1] = info_ebx;
cpu_info[2] = info_ecx;
cpu_info[3] = info_edx;
#endif // defined(_MSC_VER) && !defined(__clang__)
#endif // defined(_MSC_VER)
}
#else // (defined(_M_IX86) || defined(_M_X64) ...
LIBYUV_API
@ -117,7 +118,7 @@ void CpuId(uint32 eax, uint32 ecx, uint32* cpu_info) {
// X86 CPUs have xgetbv to detect OS saves high parts of ymm registers.
int GetXCR0() {
uint32 xcr0 = 0u;
#if (_MSC_FULL_VER >= 160040219)
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 160040219)
xcr0 = (uint32)(_xgetbv(0)); // VS2010 SP1 required.
#elif defined(__i386__) || defined(__x86_64__)
asm(".byte 0x0f, 0x01, 0xd0" : "=a" (xcr0) : "c" (0) : "%edx");
@ -251,15 +252,11 @@ int InitCpuFlags(void) {
#endif
#if defined(__mips__) && defined(__linux__)
#if defined(__mips_dspr2)
cpu_info |= kCpuHasMIPS_DSPR2;
cpu_info |= kCpuHasDSPR2;
#endif
cpu_info |= kCpuHasMIPS;
if (getenv("LIBYUV_DISABLE_MIPS")) {
cpu_info &= ~kCpuHasMIPS;
}
if (getenv("LIBYUV_DISABLE_MIPS_DSPR2")) {
cpu_info &= ~kCpuHasMIPS_DSPR2;
if (getenv("LIBYUV_DISABLE_DSPR2")) {
cpu_info &= ~kCpuHasDSPR2;
}
#endif
#if defined(__arm__) || defined(__aarch64__)

View file

@ -255,11 +255,11 @@ void MirrorPlane(const uint8* src_y, int src_stride_y,
}
#endif
// TODO(fbarchard): Mirror on mips handle unaligned memory.
#if defined(HAS_MIRRORROW_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) &&
#if defined(HAS_MIRRORROW_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) &&
IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) &&
IS_ALIGNED(dst_y, 4) && IS_ALIGNED(dst_stride_y, 4)) {
MirrorRow = MirrorRow_MIPS_DSPR2;
MirrorRow = MirrorRow_DSPR2;
}
#endif
@ -677,7 +677,7 @@ int I420Blend(const uint8* src_y0, int src_stride_y0,
#if defined(HAS_BLENDPLANEROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) {
BlendPlaneRow = BlendPlaneRow_Any_SSSE3;
BlendPlaneRow = BlendPlaneRow_Any_SSSE3;
if (IS_ALIGNED(halfwidth, 8)) {
BlendPlaneRow = BlendPlaneRow_SSSE3;
}
@ -685,33 +685,45 @@ int I420Blend(const uint8* src_y0, int src_stride_y0,
#endif
#if defined(HAS_BLENDPLANEROW_AVX2)
if (TestCpuFlag(kCpuHasAVX2)) {
BlendPlaneRow = BlendPlaneRow_Any_AVX2;
BlendPlaneRow = BlendPlaneRow_Any_AVX2;
if (IS_ALIGNED(halfwidth, 32)) {
BlendPlaneRow = BlendPlaneRow_AVX2;
}
}
#endif
if (!IS_ALIGNED(width, 2)) {
ScaleRowDown2 = ScaleRowDown2Box_Odd_C;
}
#if defined(HAS_SCALEROWDOWN2_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
ScaleRowDown2 = ScaleRowDown2Box_Any_NEON;
if (IS_ALIGNED(halfwidth, 16)) {
ScaleRowDown2 = ScaleRowDown2Box_NEON;
ScaleRowDown2 = ScaleRowDown2Box_Odd_NEON;
if (IS_ALIGNED(width, 2)) {
ScaleRowDown2 = ScaleRowDown2Box_Any_NEON;
if (IS_ALIGNED(halfwidth, 16)) {
ScaleRowDown2 = ScaleRowDown2Box_NEON;
}
}
}
#endif
#if defined(HAS_SCALEROWDOWN2_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) {
ScaleRowDown2 = ScaleRowDown2Box_Any_SSSE3;
if (IS_ALIGNED(halfwidth, 16)) {
ScaleRowDown2 = ScaleRowDown2Box_SSSE3;
ScaleRowDown2 = ScaleRowDown2Box_Odd_SSSE3;
if (IS_ALIGNED(width, 2)) {
ScaleRowDown2 = ScaleRowDown2Box_Any_SSSE3;
if (IS_ALIGNED(halfwidth, 16)) {
ScaleRowDown2 = ScaleRowDown2Box_SSSE3;
}
}
}
#endif
#if defined(HAS_SCALEROWDOWN2_AVX2)
if (TestCpuFlag(kCpuHasAVX2)) {
ScaleRowDown2 = ScaleRowDown2Box_Any_AVX2;
if (IS_ALIGNED(halfwidth, 32)) {
ScaleRowDown2 = ScaleRowDown2Box_AVX2;
ScaleRowDown2 = ScaleRowDown2Box_Odd_AVX2;
if (IS_ALIGNED(width, 2)) {
ScaleRowDown2 = ScaleRowDown2Box_Any_AVX2;
if (IS_ALIGNED(halfwidth, 32)) {
ScaleRowDown2 = ScaleRowDown2Box_AVX2;
}
}
}
#endif
@ -974,13 +986,13 @@ static int I422ToRGBAMatrix(const uint8* src_y, int src_stride_y,
}
}
#endif
#if defined(HAS_I422TORGBAROW_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(width, 4) &&
#if defined(HAS_I422TORGBAROW_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(width, 4) &&
IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) &&
IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) &&
IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) &&
IS_ALIGNED(dst_rgba, 4) && IS_ALIGNED(dst_stride_rgba, 4)) {
I422ToRGBARow = I422ToRGBARow_MIPS_DSPR2;
I422ToRGBARow = I422ToRGBARow_DSPR2;
}
#endif
@ -1894,19 +1906,18 @@ int InterpolatePlane(const uint8* src0, int src_stride0,
}
}
#endif
#if defined(HAS_INTERPOLATEROW_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) &&
#if defined(HAS_INTERPOLATEROW_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) &&
IS_ALIGNED(src0, 4) && IS_ALIGNED(src_stride0, 4) &&
IS_ALIGNED(src1, 4) && IS_ALIGNED(src_stride1, 4) &&
IS_ALIGNED(dst, 4) && IS_ALIGNED(dst_stride, 4) &&
IS_ALIGNED(width, 4)) {
InterpolateRow = InterpolateRow_MIPS_DSPR2;
InterpolateRow = InterpolateRow_DSPR2;
}
#endif
for (y = 0; y < height; ++y) {
InterpolateRow(dst, src0, src1 - src0,
width, interpolation);
InterpolateRow(dst, src0, src1 - src0, width, interpolation);
src0 += src_stride0;
src1 += src_stride1;
dst += dst_stride;
@ -2412,6 +2423,9 @@ int ARGBCopyYToAlpha(const uint8* src_y, int src_stride_y,
return 0;
}
// TODO(fbarchard): Consider if width is even Y channel can be split
// directly. A SplitUVRow_Odd function could copy the remaining chroma.
LIBYUV_API
int YUY2ToNV12(const uint8* src_yuy2, int src_stride_yuy2,
uint8* dst_y, int dst_stride_y,
@ -2486,22 +2500,24 @@ int YUY2ToNV12(const uint8* src_yuy2, int src_stride_yuy2,
{
int awidth = halfwidth * 2;
// 2 rows of uv
align_buffer_64(rows, awidth * 2);
// row of y and 2 rows of uv
align_buffer_64(rows, awidth * 3);
for (y = 0; y < height - 1; y += 2) {
// Split Y from UV.
SplitUVRow(src_yuy2, dst_y, rows, awidth);
SplitUVRow(src_yuy2 + src_stride_yuy2, dst_y + dst_stride_y,
rows + awidth, awidth);
InterpolateRow(dst_uv, rows, awidth, awidth, 128);
SplitUVRow(src_yuy2, rows, rows + awidth, awidth);
memcpy(dst_y, rows, width);
SplitUVRow(src_yuy2 + src_stride_yuy2, rows, rows + awidth * 2, awidth);
memcpy(dst_y + dst_stride_y, rows, width);
InterpolateRow(dst_uv, rows + awidth, awidth, awidth, 128);
src_yuy2 += src_stride_yuy2 * 2;
dst_y += dst_stride_y * 2;
dst_uv += dst_stride_uv;
}
if (height & 1) {
// Split Y from UV.
SplitUVRow(src_yuy2, dst_y, dst_uv, awidth);
SplitUVRow(src_yuy2, rows, dst_uv, awidth);
memcpy(dst_y, rows, width);
}
free_aligned_buffer_64(rows);
}
@ -2582,22 +2598,24 @@ int UYVYToNV12(const uint8* src_uyvy, int src_stride_uyvy,
{
int awidth = halfwidth * 2;
// 2 rows of uv
align_buffer_64(rows, awidth * 2);
// row of y and 2 rows of uv
align_buffer_64(rows, awidth * 3);
for (y = 0; y < height - 1; y += 2) {
// Split Y from UV.
SplitUVRow(src_uyvy, rows, dst_y, awidth);
SplitUVRow(src_uyvy + src_stride_uyvy, rows + awidth,
dst_y + dst_stride_y, awidth);
InterpolateRow(dst_uv, rows, awidth, awidth, 128);
SplitUVRow(src_uyvy, rows + awidth, rows, awidth);
memcpy(dst_y, rows, width);
SplitUVRow(src_uyvy + src_stride_uyvy, rows + awidth * 2, rows, awidth);
memcpy(dst_y + dst_stride_y, rows, width);
InterpolateRow(dst_uv, rows + awidth, awidth, awidth, 128);
src_uyvy += src_stride_uyvy * 2;
dst_y += dst_stride_y * 2;
dst_uv += dst_stride_uv;
}
if (height & 1) {
// Split Y from UV.
SplitUVRow(src_uyvy, dst_uv, dst_y, awidth);
SplitUVRow(src_uyvy, dst_uv, rows, awidth);
memcpy(dst_y, rows, width);
}
free_aligned_buffer_64(rows);
}

View file

@ -49,13 +49,13 @@ void TransposePlane(const uint8* src, int src_stride,
}
}
#endif
#if defined(HAS_TRANSPOSEWX8_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2)) {
#if defined(HAS_TRANSPOSEWX8_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2)) {
if (IS_ALIGNED(width, 4) &&
IS_ALIGNED(src, 4) && IS_ALIGNED(src_stride, 4)) {
TransposeWx8 = TransposeWx8_Fast_MIPS_DSPR2;
TransposeWx8 = TransposeWx8_Fast_DSPR2;
} else {
TransposeWx8 = TransposeWx8_MIPS_DSPR2;
TransposeWx8 = TransposeWx8_DSPR2;
}
}
#endif
@ -134,11 +134,11 @@ void RotatePlane180(const uint8* src, int src_stride,
}
#endif
// TODO(fbarchard): Mirror on mips handle unaligned memory.
#if defined(HAS_MIRRORROW_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) &&
#if defined(HAS_MIRRORROW_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) &&
IS_ALIGNED(src, 4) && IS_ALIGNED(src_stride, 4) &&
IS_ALIGNED(dst, 4) && IS_ALIGNED(dst_stride, 4)) {
MirrorRow = MirrorRow_MIPS_DSPR2;
MirrorRow = MirrorRow_DSPR2;
}
#endif
#if defined(HAS_COPYROW_SSE2)
@ -203,10 +203,10 @@ void TransposeUV(const uint8* src, int src_stride,
}
}
#endif
#if defined(HAS_TRANSPOSEUVWX8_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(width, 2) &&
#if defined(HAS_TRANSPOSEUVWX8_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(width, 2) &&
IS_ALIGNED(src, 4) && IS_ALIGNED(src_stride, 4)) {
TransposeUVWx8 = TransposeUVWx8_MIPS_DSPR2;
TransposeUVWx8 = TransposeUVWx8_DSPR2;
}
#endif
@ -267,22 +267,22 @@ void RotateUV180(const uint8* src, int src_stride,
uint8* dst_b, int dst_stride_b,
int width, int height) {
int i;
void (*MirrorRowUV)(const uint8* src, uint8* dst_u, uint8* dst_v, int width) =
void (*MirrorUVRow)(const uint8* src, uint8* dst_u, uint8* dst_v, int width) =
MirrorUVRow_C;
#if defined(HAS_MIRRORUVROW_NEON)
if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) {
MirrorRowUV = MirrorUVRow_NEON;
MirrorUVRow = MirrorUVRow_NEON;
}
#endif
#if defined(HAS_MIRRORROW_UV_SSSE3)
#if defined(HAS_MIRRORUVROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 16)) {
MirrorRowUV = MirrorUVRow_SSSE3;
MirrorUVRow = MirrorUVRow_SSSE3;
}
#endif
#if defined(HAS_MIRRORUVROW_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) &&
#if defined(HAS_MIRRORUVROW_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) &&
IS_ALIGNED(src, 4) && IS_ALIGNED(src_stride, 4)) {
MirrorRowUV = MirrorUVRow_MIPS_DSPR2;
MirrorUVRow = MirrorUVRow_DSPR2;
}
#endif
@ -290,7 +290,7 @@ void RotateUV180(const uint8* src, int src_stride,
dst_b += dst_stride_b * (height - 1);
for (i = 0; i < height; ++i) {
MirrorRowUV(src, dst_a, dst_b, width);
MirrorUVRow(src, dst_a, dst_b, width);
src += src_stride;
dst_a -= dst_stride_a;
dst_b -= dst_stride_b;

View file

@ -38,8 +38,8 @@ TANY(TransposeWx8_Any_SSSE3, TransposeWx8_SSSE3, 7)
#ifdef HAS_TRANSPOSEWX8_FAST_SSSE3
TANY(TransposeWx8_Fast_Any_SSSE3, TransposeWx8_Fast_SSSE3, 15)
#endif
#ifdef HAS_TRANSPOSEWX8_MIPS_DSPR2
TANY(TransposeWx8_Any_MIPS_DSPR2, TransposeWx8_MIPS_DSPR2, 7)
#ifdef HAS_TRANSPOSEWX8_DSPR2
TANY(TransposeWx8_Any_DSPR2, TransposeWx8_DSPR2, 7)
#endif
#undef TANY
@ -64,8 +64,8 @@ TUVANY(TransposeUVWx8_Any_NEON, TransposeUVWx8_NEON, 7)
#ifdef HAS_TRANSPOSEUVWX8_SSE2
TUVANY(TransposeUVWx8_Any_SSE2, TransposeUVWx8_SSE2, 7)
#endif
#ifdef HAS_TRANSPOSEUVWX8_MIPS_DSPR2
TUVANY(TransposeUVWx8_Any_MIPS_DSPR2, TransposeUVWx8_MIPS_DSPR2, 7)
#ifdef HAS_TRANSPOSEUVWX8_DSPR2
TUVANY(TransposeUVWx8_Any_DSPR2, TransposeUVWx8_DSPR2, 7)
#endif
#undef TUVANY

View file

@ -22,7 +22,7 @@ extern "C" {
defined(__mips_dsp) && (__mips_dsp_rev >= 2) && \
(_MIPS_SIM == _MIPS_SIM_ABI32)
void TransposeWx8_MIPS_DSPR2(const uint8* src, int src_stride,
void TransposeWx8_DSPR2(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width) {
__asm__ __volatile__ (
".set push \n"
@ -106,7 +106,7 @@ void TransposeWx8_MIPS_DSPR2(const uint8* src, int src_stride,
);
}
void TransposeWx8_Fast_MIPS_DSPR2(const uint8* src, int src_stride,
void TransposeWx8_Fast_DSPR2(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width) {
__asm__ __volatile__ (
".set noat \n"
@ -308,7 +308,7 @@ void TransposeWx8_Fast_MIPS_DSPR2(const uint8* src, int src_stride,
);
}
void TransposeUVWx8_MIPS_DSPR2(const uint8* src, int src_stride,
void TransposeUVWx8_DSPR2(const uint8* src, int src_stride,
uint8* dst_a, int dst_stride_a,
uint8* dst_b, int dst_stride_b,
int width) {

View file

@ -27,7 +27,7 @@ static uvec8 kVTbl4x4Transpose =
void TransposeWx8_NEON(const uint8* src, int src_stride,
uint8* dst, int dst_stride,
int width) {
const uint8* src_temp = NULL;
const uint8* src_temp;
asm volatile (
// loops are on blocks of 8. loop will stop when
// counter gets to or below 0. starting the counter
@ -229,7 +229,7 @@ void TransposeWx8_NEON(const uint8* src, int src_stride,
"4: \n"
: "+r"(src_temp), // %0
: "=&r"(src_temp), // %0
"+r"(src), // %1
"+r"(src_stride), // %2
"+r"(dst), // %3
@ -247,7 +247,7 @@ void TransposeUVWx8_NEON(const uint8* src, int src_stride,
uint8* dst_a, int dst_stride_a,
uint8* dst_b, int dst_stride_b,
int width) {
const uint8* src_temp = NULL;
const uint8* src_temp;
asm volatile (
// loops are on blocks of 8. loop will stop when
// counter gets to or below 0. starting the counter
@ -512,7 +512,7 @@ void TransposeUVWx8_NEON(const uint8* src, int src_stride,
"4: \n"
: "+r"(src_temp), // %0
: "=&r"(src_temp), // %0
"+r"(src), // %1
"+r"(src_stride), // %2
"+r"(dst_a), // %3

View file

@ -26,7 +26,7 @@ static uvec8 kVTbl4x4Transpose =
void TransposeWx8_NEON(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width) {
const uint8* src_temp = NULL;
const uint8* src_temp;
int64 width64 = (int64) width; // Work around clang 3.4 warning.
asm volatile (
// loops are on blocks of 8. loop will stop when
@ -235,7 +235,7 @@ void TransposeWx8_NEON(const uint8* src, int src_stride,
"4: \n"
: "+r"(src_temp), // %0
: "=&r"(src_temp), // %0
"+r"(src), // %1
"+r"(dst), // %2
"+r"(width64) // %3
@ -255,7 +255,7 @@ void TransposeUVWx8_NEON(const uint8* src, int src_stride,
uint8* dst_a, int dst_stride_a,
uint8* dst_b, int dst_stride_b,
int width) {
const uint8* src_temp = NULL;
const uint8* src_temp;
int64 width64 = (int64) width; // Work around clang 3.4 warning.
asm volatile (
// loops are on blocks of 8. loop will stop when
@ -520,7 +520,7 @@ void TransposeUVWx8_NEON(const uint8* src, int src_stride,
"4: \n"
: "+r"(src_temp), // %0
: "=&r"(src_temp), // %0
"+r"(src), // %1
"+r"(dst_a), // %2
"+r"(dst_b), // %3

View file

@ -596,8 +596,8 @@ ANY11T(InterpolateRow_Any_SSSE3, InterpolateRow_SSSE3, 1, 1, 15)
#ifdef HAS_INTERPOLATEROW_NEON
ANY11T(InterpolateRow_Any_NEON, InterpolateRow_NEON, 1, 1, 15)
#endif
#ifdef HAS_INTERPOLATEROW_MIPS_DSPR2
ANY11T(InterpolateRow_Any_MIPS_DSPR2, InterpolateRow_MIPS_DSPR2, 1, 1, 3)
#ifdef HAS_INTERPOLATEROW_DSPR2
ANY11T(InterpolateRow_Any_DSPR2, InterpolateRow_DSPR2, 1, 1, 3)
#endif
#undef ANY11T
@ -705,8 +705,8 @@ ANY12(SplitUVRow_Any_AVX2, SplitUVRow_AVX2, 0, 2, 0, 31)
#ifdef HAS_SPLITUVROW_NEON
ANY12(SplitUVRow_Any_NEON, SplitUVRow_NEON, 0, 2, 0, 15)
#endif
#ifdef HAS_SPLITUVROW_MIPS_DSPR2
ANY12(SplitUVRow_Any_MIPS_DSPR2, SplitUVRow_MIPS_DSPR2, 0, 2, 0, 15)
#ifdef HAS_SPLITUVROW_DSPR2
ANY12(SplitUVRow_Any_DSPR2, SplitUVRow_DSPR2, 0, 2, 0, 15)
#endif
#ifdef HAS_ARGBTOUV444ROW_SSSE3
ANY12(ARGBToUV444Row_Any_SSSE3, ARGBToUV444Row_SSSE3, 0, 4, 0, 15)
@ -715,16 +715,12 @@ ANY12(ARGBToUV444Row_Any_SSSE3, ARGBToUV444Row_SSSE3, 0, 4, 0, 15)
ANY12(YUY2ToUV422Row_Any_AVX2, YUY2ToUV422Row_AVX2, 1, 4, 1, 31)
ANY12(UYVYToUV422Row_Any_AVX2, UYVYToUV422Row_AVX2, 1, 4, 1, 31)
#endif
#ifdef HAS_ARGBTOUV422ROW_SSSE3
ANY12(ARGBToUV422Row_Any_SSSE3, ARGBToUV422Row_SSSE3, 0, 4, 1, 15)
#endif
#ifdef HAS_YUY2TOUV422ROW_SSE2
ANY12(YUY2ToUV422Row_Any_SSE2, YUY2ToUV422Row_SSE2, 1, 4, 1, 15)
ANY12(UYVYToUV422Row_Any_SSE2, UYVYToUV422Row_SSE2, 1, 4, 1, 15)
#endif
#ifdef HAS_YUY2TOUV422ROW_NEON
ANY12(ARGBToUV444Row_Any_NEON, ARGBToUV444Row_NEON, 0, 4, 0, 7)
ANY12(ARGBToUV422Row_Any_NEON, ARGBToUV422Row_NEON, 0, 4, 1, 15)
ANY12(ARGBToUV411Row_Any_NEON, ARGBToUV411Row_NEON, 0, 4, 2, 31)
ANY12(YUY2ToUV422Row_Any_NEON, YUY2ToUV422Row_NEON, 1, 4, 1, 15)
ANY12(UYVYToUV422Row_Any_NEON, UYVYToUV422Row_NEON, 1, 4, 1, 15)
@ -760,6 +756,9 @@ ANY12(UYVYToUV422Row_Any_NEON, UYVYToUV422Row_NEON, 1, 4, 1, 15)
#ifdef HAS_ARGBTOUVROW_AVX2
ANY12S(ARGBToUVRow_Any_AVX2, ARGBToUVRow_AVX2, 0, 4, 31)
#endif
#ifdef HAS_ARGBTOUVJROW_AVX2
ANY12S(ARGBToUVJRow_Any_AVX2, ARGBToUVJRow_AVX2, 0, 4, 31)
#endif
#ifdef HAS_ARGBTOUVROW_SSSE3
ANY12S(ARGBToUVRow_Any_SSSE3, ARGBToUVRow_SSSE3, 0, 4, 15)
ANY12S(ARGBToUVJRow_Any_SSSE3, ARGBToUVJRow_SSSE3, 0, 4, 15)

View file

@ -433,28 +433,6 @@ void NAME ## ToUVJRow_C(const uint8* src_rgb0, int src_stride_rgb, \
MAKEROWYJ(ARGB, 2, 1, 0, 4)
#undef MAKEROWYJ
void ARGBToUVJ422Row_C(const uint8* src_argb,
uint8* dst_u, uint8* dst_v, int width) {
int x;
for (x = 0; x < width - 1; x += 2) {
uint8 ab = (src_argb[0] + src_argb[4]) >> 1;
uint8 ag = (src_argb[1] + src_argb[5]) >> 1;
uint8 ar = (src_argb[2] + src_argb[6]) >> 1;
dst_u[0] = RGBToUJ(ar, ag, ab);
dst_v[0] = RGBToVJ(ar, ag, ab);
src_argb += 8;
dst_u += 1;
dst_v += 1;
}
if (width & 1) {
uint8 ab = src_argb[0];
uint8 ag = src_argb[1];
uint8 ar = src_argb[2];
dst_u[0] = RGBToUJ(ar, ag, ab);
dst_v[0] = RGBToVJ(ar, ag, ab);
}
}
void RGB565ToYRow_C(const uint8* src_rgb565, uint8* dst_y, int width) {
int x;
for (x = 0; x < width; ++x) {
@ -658,28 +636,6 @@ void ARGBToUV444Row_C(const uint8* src_argb,
}
}
void ARGBToUV422Row_C(const uint8* src_argb,
uint8* dst_u, uint8* dst_v, int width) {
int x;
for (x = 0; x < width - 1; x += 2) {
uint8 ab = (src_argb[0] + src_argb[4]) >> 1;
uint8 ag = (src_argb[1] + src_argb[5]) >> 1;
uint8 ar = (src_argb[2] + src_argb[6]) >> 1;
dst_u[0] = RGBToU(ar, ag, ab);
dst_v[0] = RGBToV(ar, ag, ab);
src_argb += 8;
dst_u += 1;
dst_v += 1;
}
if (width & 1) {
uint8 ab = src_argb[0];
uint8 ag = src_argb[1];
uint8 ar = src_argb[2];
dst_u[0] = RGBToU(ar, ag, ab);
dst_v[0] = RGBToV(ar, ag, ab);
}
}
void ARGBToUV411Row_C(const uint8* src_argb,
uint8* dst_u, uint8* dst_v, int width) {
int x;
@ -2191,7 +2147,7 @@ void ARGBAffineRow_C(const uint8* src_argb, int src_argb_stride,
}
// Blend 2 rows into 1.
static void HalfRow_C(const uint8* src_uv, int src_uv_stride,
static void HalfRow_C(const uint8* src_uv, ptrdiff_t src_uv_stride,
uint8* dst_uv, int width) {
int x;
for (x = 0; x < width; ++x) {
@ -2199,7 +2155,7 @@ static void HalfRow_C(const uint8* src_uv, int src_uv_stride,
}
}
static void HalfRow_16_C(const uint16* src_uv, int src_uv_stride,
static void HalfRow_16_C(const uint16* src_uv, ptrdiff_t src_uv_stride,
uint16* dst_uv, int width) {
int x;
for (x = 0; x < width; ++x) {
@ -2220,7 +2176,7 @@ void InterpolateRow_C(uint8* dst_ptr, const uint8* src_ptr,
return;
}
if (y1_fraction == 128) {
HalfRow_C(src_ptr, (int)(src_stride), dst_ptr, width);
HalfRow_C(src_ptr, src_stride, dst_ptr, width);
return;
}
for (x = 0; x < width - 1; x += 2) {
@ -2250,7 +2206,7 @@ void InterpolateRow_16_C(uint16* dst_ptr, const uint16* src_ptr,
return;
}
if (source_y_fraction == 128) {
HalfRow_16_C(src_ptr, (int)(src_stride), dst_ptr, width);
HalfRow_16_C(src_ptr, src_stride, dst_ptr, width);
return;
}
for (x = 0; x < width - 1; x += 2) {
@ -2539,7 +2495,11 @@ void I422ToRGB565Row_AVX2(const uint8* src_y,
while (width > 0) {
int twidth = width > MAXTWIDTH ? MAXTWIDTH : width;
I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth);
#if defined(HAS_ARGBTORGB565ROW_AVX2)
ARGBToRGB565Row_AVX2(row, dst_rgb565, twidth);
#else
ARGBToRGB565Row_SSE2(row, dst_rgb565, twidth);
#endif
src_y += twidth;
src_u += twidth / 2;
src_v += twidth / 2;
@ -2561,7 +2521,11 @@ void I422ToARGB1555Row_AVX2(const uint8* src_y,
while (width > 0) {
int twidth = width > MAXTWIDTH ? MAXTWIDTH : width;
I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth);
#if defined(HAS_ARGBTOARGB1555ROW_AVX2)
ARGBToARGB1555Row_AVX2(row, dst_argb1555, twidth);
#else
ARGBToARGB1555Row_SSE2(row, dst_argb1555, twidth);
#endif
src_y += twidth;
src_u += twidth / 2;
src_v += twidth / 2;
@ -2583,7 +2547,11 @@ void I422ToARGB4444Row_AVX2(const uint8* src_y,
while (width > 0) {
int twidth = width > MAXTWIDTH ? MAXTWIDTH : width;
I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth);
#if defined(HAS_ARGBTOARGB4444ROW_AVX2)
ARGBToARGB4444Row_AVX2(row, dst_argb4444, twidth);
#else
ARGBToARGB4444Row_SSE2(row, dst_argb4444, twidth);
#endif
src_y += twidth;
src_u += twidth / 2;
src_v += twidth / 2;
@ -2627,7 +2595,11 @@ void NV12ToRGB565Row_AVX2(const uint8* src_y,
while (width > 0) {
int twidth = width > MAXTWIDTH ? MAXTWIDTH : width;
NV12ToARGBRow_AVX2(src_y, src_uv, row, yuvconstants, twidth);
#if defined(HAS_ARGBTORGB565ROW_AVX2)
ARGBToRGB565Row_AVX2(row, dst_rgb565, twidth);
#else
ARGBToRGB565Row_SSE2(row, dst_rgb565, twidth);
#endif
src_y += twidth;
src_uv += twidth;
dst_rgb565 += twidth * 2;

View file

@ -1023,6 +1023,67 @@ void ARGBToUVRow_AVX2(const uint8* src_argb0, int src_stride_argb,
}
#endif // HAS_ARGBTOUVROW_AVX2
#ifdef HAS_ARGBTOUVJROW_AVX2
void ARGBToUVJRow_AVX2(const uint8* src_argb0, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width) {
asm volatile (
"vbroadcastf128 %5,%%ymm5 \n"
"vbroadcastf128 %6,%%ymm6 \n"
"vbroadcastf128 %7,%%ymm7 \n"
"sub %1,%2 \n"
LABELALIGN
"1: \n"
"vmovdqu " MEMACCESS(0) ",%%ymm0 \n"
"vmovdqu " MEMACCESS2(0x20,0) ",%%ymm1 \n"
"vmovdqu " MEMACCESS2(0x40,0) ",%%ymm2 \n"
"vmovdqu " MEMACCESS2(0x60,0) ",%%ymm3 \n"
VMEMOPREG(vpavgb,0x00,0,4,1,ymm0,ymm0) // vpavgb (%0,%4,1),%%ymm0,%%ymm0
VMEMOPREG(vpavgb,0x20,0,4,1,ymm1,ymm1)
VMEMOPREG(vpavgb,0x40,0,4,1,ymm2,ymm2)
VMEMOPREG(vpavgb,0x60,0,4,1,ymm3,ymm3)
"lea " MEMLEA(0x80,0) ",%0 \n"
"vshufps $0x88,%%ymm1,%%ymm0,%%ymm4 \n"
"vshufps $0xdd,%%ymm1,%%ymm0,%%ymm0 \n"
"vpavgb %%ymm4,%%ymm0,%%ymm0 \n"
"vshufps $0x88,%%ymm3,%%ymm2,%%ymm4 \n"
"vshufps $0xdd,%%ymm3,%%ymm2,%%ymm2 \n"
"vpavgb %%ymm4,%%ymm2,%%ymm2 \n"
"vpmaddubsw %%ymm7,%%ymm0,%%ymm1 \n"
"vpmaddubsw %%ymm7,%%ymm2,%%ymm3 \n"
"vpmaddubsw %%ymm6,%%ymm0,%%ymm0 \n"
"vpmaddubsw %%ymm6,%%ymm2,%%ymm2 \n"
"vphaddw %%ymm3,%%ymm1,%%ymm1 \n"
"vphaddw %%ymm2,%%ymm0,%%ymm0 \n"
"vpaddw %%ymm5,%%ymm0,%%ymm0 \n"
"vpaddw %%ymm5,%%ymm1,%%ymm1 \n"
"vpsraw $0x8,%%ymm1,%%ymm1 \n"
"vpsraw $0x8,%%ymm0,%%ymm0 \n"
"vpacksswb %%ymm0,%%ymm1,%%ymm0 \n"
"vpermq $0xd8,%%ymm0,%%ymm0 \n"
"vpshufb %8,%%ymm0,%%ymm0 \n"
"vextractf128 $0x0,%%ymm0," MEMACCESS(1) " \n"
VEXTOPMEM(vextractf128,1,ymm0,0x0,1,2,1) // vextractf128 $1,%%ymm0,(%1,%2,1)
"lea " MEMLEA(0x10,1) ",%1 \n"
"sub $0x20,%3 \n"
"jg 1b \n"
"vzeroupper \n"
: "+r"(src_argb0), // %0
"+r"(dst_u), // %1
"+r"(dst_v), // %2
"+rm"(width) // %3
: "r"((intptr_t)(src_stride_argb)), // %4
"m"(kAddUVJ128), // %5
"m"(kARGBToVJ), // %6
"m"(kARGBToUJ), // %7
"m"(kShufARGBToUV_AVX) // %8
: "memory", "cc", NACL_R14
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"
);
}
#endif // HAS_ARGBTOUVJROW_AVX2
#ifdef HAS_ARGBTOUVJROW_SSSE3
void ARGBToUVJRow_SSSE3(const uint8* src_argb0, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width) {
@ -1144,59 +1205,6 @@ void ARGBToUV444Row_SSSE3(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
}
#endif // HAS_ARGBTOUV444ROW_SSSE3
#ifdef HAS_ARGBTOUV422ROW_SSSE3
void ARGBToUV422Row_SSSE3(const uint8* src_argb0,
uint8* dst_u, uint8* dst_v, int width) {
asm volatile (
"movdqa %4,%%xmm3 \n"
"movdqa %5,%%xmm4 \n"
"movdqa %6,%%xmm5 \n"
"sub %1,%2 \n"
LABELALIGN
"1: \n"
"movdqu " MEMACCESS(0) ",%%xmm0 \n"
"movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n"
"movdqu " MEMACCESS2(0x20,0) ",%%xmm2 \n"
"movdqu " MEMACCESS2(0x30,0) ",%%xmm6 \n"
"lea " MEMLEA(0x40,0) ",%0 \n"
"movdqa %%xmm0,%%xmm7 \n"
"shufps $0x88,%%xmm1,%%xmm0 \n"
"shufps $0xdd,%%xmm1,%%xmm7 \n"
"pavgb %%xmm7,%%xmm0 \n"
"movdqa %%xmm2,%%xmm7 \n"
"shufps $0x88,%%xmm6,%%xmm2 \n"
"shufps $0xdd,%%xmm6,%%xmm7 \n"
"pavgb %%xmm7,%%xmm2 \n"
"movdqa %%xmm0,%%xmm1 \n"
"movdqa %%xmm2,%%xmm6 \n"
"pmaddubsw %%xmm4,%%xmm0 \n"
"pmaddubsw %%xmm4,%%xmm2 \n"
"pmaddubsw %%xmm3,%%xmm1 \n"
"pmaddubsw %%xmm3,%%xmm6 \n"
"phaddw %%xmm2,%%xmm0 \n"
"phaddw %%xmm6,%%xmm1 \n"
"psraw $0x8,%%xmm0 \n"
"psraw $0x8,%%xmm1 \n"
"packsswb %%xmm1,%%xmm0 \n"
"paddb %%xmm5,%%xmm0 \n"
"movlps %%xmm0," MEMACCESS(1) " \n"
MEMOPMEM(movhps,xmm0,0x00,1,2,1) // movhps %%xmm0,(%1,%2,1)
"lea " MEMLEA(0x8,1) ",%1 \n"
"sub $0x10,%3 \n"
"jg 1b \n"
: "+r"(src_argb0), // %0
"+r"(dst_u), // %1
"+r"(dst_v), // %2
"+rm"(width) // %3
: "m"(kARGBToV), // %4
"m"(kARGBToU), // %5
"m"(kAddUV128) // %6
: "memory", "cc", NACL_R14
"xmm0", "xmm1", "xmm2", "xmm6", "xmm7"
);
}
#endif // HAS_ARGBTOUV422ROW_SSSE3
void BGRAToYRow_SSSE3(const uint8* src_bgra, uint8* dst_y, int width) {
asm volatile (
"movdqa %4,%%xmm5 \n"
@ -1484,7 +1492,7 @@ void RGBAToUVRow_SSSE3(const uint8* src_rgba0, int src_stride_rgba,
#if defined(HAS_I422TOARGBROW_SSSE3) || defined(HAS_I422TOARGBROW_AVX2)
// Read 8 UV from 411
// Read 8 UV from 444
#define READYUV444 \
"movq " MEMACCESS([u_buf]) ",%%xmm0 \n" \
MEMOPREG(movq, 0x00, [u_buf], [v_buf], 1, xmm1) \
@ -1528,7 +1536,7 @@ void RGBAToUVRow_SSSE3(const uint8* src_rgba0, int src_stride_rgba,
#define READYUV411_TEMP \
"movzwl " MEMACCESS([u_buf]) ",%[temp] \n" \
"movd %[temp],%%xmm0 \n" \
MEMOPARG(movzwl,0x00,[u_buf],[v_buf],1,[temp]) " \n" \
MEMOPARG(movzwl, 0x00, [u_buf], [v_buf], 1, [temp]) " \n" \
"movd %[temp],%%xmm1 \n" \
"lea " MEMLEA(0x2, [u_buf]) ",%[u_buf] \n" \
"punpcklbw %%xmm1,%%xmm0 \n" \
@ -1803,7 +1811,7 @@ void OMITFP I411ToARGBRow_SSSE3(const uint8* y_buf,
uint8* dst_argb,
const struct YuvConstants* yuvconstants,
int width) {
int temp = 0;
int temp;
asm volatile (
YUVTORGB_SETUP(yuvconstants)
"sub %[u_buf],%[v_buf] \n"
@ -1815,15 +1823,15 @@ void OMITFP I411ToARGBRow_SSSE3(const uint8* y_buf,
STOREARGB
"subl $0x8,%[width] \n"
"jg 1b \n"
: [y_buf]"+r"(y_buf), // %[y_buf]
[u_buf]"+r"(u_buf), // %[u_buf]
[v_buf]"+r"(v_buf), // %[v_buf]
: [y_buf]"+r"(y_buf), // %[y_buf]
[u_buf]"+r"(u_buf), // %[u_buf]
[v_buf]"+r"(v_buf), // %[v_buf]
[dst_argb]"+r"(dst_argb), // %[dst_argb]
[temp]"+r"(temp), // %[temp]
[temp]"=&r"(temp), // %[temp]
#if defined(__i386__) && defined(__pic__)
[width]"+m"(width) // %[width]
[width]"+m"(width) // %[width]
#else
[width]"+rm"(width) // %[width]
[width]"+rm"(width) // %[width]
#endif
: [yuvconstants]"r"(yuvconstants) // %[yuvconstants]
: "memory", "cc", NACL_R14 YUVTORGB_REGS
@ -2005,6 +2013,20 @@ void OMITFP I422ToRGBARow_SSSE3(const uint8* y_buf,
"vpermq $0xd8,%%ymm5,%%ymm5 \n" \
"lea " MEMLEA(0x10, [a_buf]) ",%[a_buf] \n"
// Read 4 UV from 411, upsample to 16 UV.
#define READYUV411_AVX2 \
"vmovd " MEMACCESS([u_buf]) ",%%xmm0 \n" \
MEMOPREG(vmovd, 0x00, [u_buf], [v_buf], 1, xmm1) \
"lea " MEMLEA(0x4, [u_buf]) ",%[u_buf] \n" \
"vpunpcklbw %%ymm1,%%ymm0,%%ymm0 \n" \
"vpunpcklwd %%ymm0,%%ymm0,%%ymm0 \n" \
"vpermq $0xd8,%%ymm0,%%ymm0 \n" \
"vpunpckldq %%ymm0,%%ymm0,%%ymm0 \n" \
"vmovdqu " MEMACCESS([y_buf]) ",%%xmm4 \n" \
"vpermq $0xd8,%%ymm4,%%ymm4 \n" \
"vpunpcklbw %%ymm4,%%ymm4,%%ymm4 \n" \
"lea " MEMLEA(0x10, [y_buf]) ",%[y_buf] \n"
// Read 8 UV from NV12, upsample to 16 UV.
#define READNV12_AVX2 \
"vmovdqu " MEMACCESS([uv_buf]) ",%%xmm0 \n" \
@ -2071,7 +2093,7 @@ void OMITFP I422ToRGBARow_SSSE3(const uint8* y_buf,
"vpackuswb %%ymm2,%%ymm2,%%ymm2 \n"
#define YUVTORGB_REGS_AVX2 \
"xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14",
#else// Convert 16 pixels: 16 UV and 16 Y.
#else // Convert 16 pixels: 16 UV and 16 Y.
#define YUVTORGB_SETUP_AVX2(yuvconstants)
#define YUVTORGB_AVX2(yuvconstants) \
"vpmaddubsw " MEMACCESS2(64, [yuvconstants]) ",%%ymm0,%%ymm2 \n" \
@ -2120,7 +2142,7 @@ void OMITFP I444ToARGBRow_AVX2(const uint8* y_buf,
asm volatile (
YUVTORGB_SETUP_AVX2(yuvconstants)
"sub %[u_buf],%[v_buf] \n"
"vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n"
"vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n"
LABELALIGN
"1: \n"
READYUV444_AVX2
@ -2141,6 +2163,39 @@ void OMITFP I444ToARGBRow_AVX2(const uint8* y_buf,
}
#endif // HAS_I444TOARGBROW_AVX2
#ifdef HAS_I411TOARGBROW_AVX2
// 16 pixels
// 4 UV values upsampled to 16 UV, mixed with 16 Y producing 16 ARGB (64 bytes).
void OMITFP I411ToARGBRow_AVX2(const uint8* y_buf,
const uint8* u_buf,
const uint8* v_buf,
uint8* dst_argb,
const struct YuvConstants* yuvconstants,
int width) {
asm volatile (
YUVTORGB_SETUP_AVX2(yuvconstants)
"sub %[u_buf],%[v_buf] \n"
"vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n"
LABELALIGN
"1: \n"
READYUV411_AVX2
YUVTORGB_AVX2(yuvconstants)
STOREARGB_AVX2
"sub $0x10,%[width] \n"
"jg 1b \n"
"vzeroupper \n"
: [y_buf]"+r"(y_buf), // %[y_buf]
[u_buf]"+r"(u_buf), // %[u_buf]
[v_buf]"+r"(v_buf), // %[v_buf]
[dst_argb]"+r"(dst_argb), // %[dst_argb]
[width]"+rm"(width) // %[width]
: [yuvconstants]"r"(yuvconstants) // %[yuvconstants]
: "memory", "cc", NACL_R14 YUVTORGB_REGS_AVX2
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"
);
}
#endif // HAS_I411TOARGBROW_AVX2
#if defined(HAS_I422TOARGBROW_AVX2)
// 16 pixels
// 8 UV values upsampled to 16 UV, mixed with 16 Y producing 16 ARGB (64 bytes).
@ -2153,7 +2208,7 @@ void OMITFP I422ToARGBRow_AVX2(const uint8* y_buf,
asm volatile (
YUVTORGB_SETUP_AVX2(yuvconstants)
"sub %[u_buf],%[v_buf] \n"
"vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n"
"vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n"
LABELALIGN
"1: \n"
READYUV422_AVX2
@ -2521,7 +2576,7 @@ void MirrorRow_AVX2(const uint8* src, uint8* dst, int width) {
}
#endif // HAS_MIRRORROW_AVX2
#ifdef HAS_MIRRORROW_UV_SSSE3
#ifdef HAS_MIRRORUVROW_SSSE3
// Shuffle table for reversing the bytes of UV channels.
static uvec8 kShuffleMirrorUV = {
14u, 12u, 10u, 8u, 6u, 4u, 2u, 0u, 15u, 13u, 11u, 9u, 7u, 5u, 3u, 1u
@ -2552,7 +2607,7 @@ void MirrorUVRow_SSSE3(const uint8* src, uint8* dst_u, uint8* dst_v,
"xmm0", "xmm1"
);
}
#endif // HAS_MIRRORROW_UV_SSSE3
#endif // HAS_MIRRORUVROW_SSSE3
#ifdef HAS_ARGBMIRRORROW_SSE2
@ -2953,7 +3008,7 @@ void ARGBCopyYToAlphaRow_AVX2(const uint8* src, uint8* dst, int width) {
#ifdef HAS_SETROW_X86
void SetRow_X86(uint8* dst, uint8 v8, int width) {
size_t width_tmp = (size_t)(width >> 2);
const uint32 v32 = v8 * 0x01010101; // Duplicate byte to all bytes.
const uint32 v32 = v8 * 0x01010101u; // Duplicate byte to all bytes.
asm volatile (
"rep stosl " MEMSTORESTRING(eax,0) " \n"
: "+D"(dst), // %0
@ -3677,7 +3732,7 @@ void ARGBAttenuateRow_AVX2(const uint8* src_argb, uint8* dst_argb, int width) {
// Unattenuate 4 pixels at a time.
void ARGBUnattenuateRow_SSE2(const uint8* src_argb, uint8* dst_argb,
int width) {
uintptr_t alpha = 0;
uintptr_t alpha;
asm volatile (
// 4 pixel loop.
LABELALIGN
@ -3708,10 +3763,10 @@ void ARGBUnattenuateRow_SSE2(const uint8* src_argb, uint8* dst_argb,
"lea " MEMLEA(0x10,1) ",%1 \n"
"sub $0x4,%2 \n"
"jg 1b \n"
: "+r"(src_argb), // %0
"+r"(dst_argb), // %1
"+r"(width), // %2
"+r"(alpha) // %3
: "+r"(src_argb), // %0
"+r"(dst_argb), // %1
"+r"(width), // %2
"=&r"(alpha) // %3
: "r"(fixed_invtbl8) // %4
: "memory", "cc", NACL_R14
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"
@ -3727,7 +3782,7 @@ static const uvec8 kUnattenShuffleAlpha_AVX2 = {
// Unattenuate 8 pixels at a time.
void ARGBUnattenuateRow_AVX2(const uint8* src_argb, uint8* dst_argb,
int width) {
uintptr_t alpha = 0;
uintptr_t alpha;
asm volatile (
"sub %0,%1 \n"
"vbroadcastf128 %5,%%ymm5 \n"
@ -3776,10 +3831,10 @@ void ARGBUnattenuateRow_AVX2(const uint8* src_argb, uint8* dst_argb,
"sub $0x8,%2 \n"
"jg 1b \n"
"vzeroupper \n"
: "+r"(src_argb), // %0
"+r"(dst_argb), // %1
"+r"(width), // %2
"+r"(alpha) // %3
: "+r"(src_argb), // %0
"+r"(dst_argb), // %1
"+r"(width), // %2
"=&r"(alpha) // %3
: "r"(fixed_invtbl8), // %4
"m"(kUnattenShuffleAlpha_AVX2) // %5
: "memory", "cc", NACL_R14
@ -4704,7 +4759,7 @@ LIBYUV_API
void ARGBAffineRow_SSE2(const uint8* src_argb, int src_argb_stride,
uint8* dst_argb, const float* src_dudv, int width) {
intptr_t src_argb_stride_temp = src_argb_stride;
intptr_t temp = 0;
intptr_t temp;
asm volatile (
"movq " MEMACCESS(3) ",%%xmm2 \n"
"movq " MEMACCESS2(0x08,3) ",%%xmm7 \n"
@ -4776,7 +4831,7 @@ void ARGBAffineRow_SSE2(const uint8* src_argb, int src_argb_stride,
"+r"(dst_argb), // %2
"+r"(src_dudv), // %3
"+rm"(width), // %4
"+r"(temp) // %5
"=&r"(temp) // %5
:
: "memory", "cc", NACL_R14
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"
@ -5002,7 +5057,7 @@ void ARGBShuffleRow_AVX2(const uint8* src_argb, uint8* dst_argb,
// For BGRAToARGB, ABGRToARGB, RGBAToARGB, and ARGBToRGBA.
void ARGBShuffleRow_SSE2(const uint8* src_argb, uint8* dst_argb,
const uint8* shuffler, int width) {
uintptr_t pixel_temp = 0u;
uintptr_t pixel_temp;
asm volatile (
"pxor %%xmm5,%%xmm5 \n"
"mov " MEMACCESS(4) ",%k2 \n"
@ -5107,11 +5162,11 @@ void ARGBShuffleRow_SSE2(const uint8* src_argb, uint8* dst_argb,
"jg 3012b \n"
"99: \n"
: "+r"(src_argb), // %0
"+r"(dst_argb), // %1
"+d"(pixel_temp), // %2
: "+r"(src_argb), // %0
"+r"(dst_argb), // %1
"=&d"(pixel_temp), // %2
"+r"(width) // %3
: "r"(shuffler) // %4
: "r"(shuffler) // %4
: "memory", "cc", NACL_R14
"xmm0", "xmm1", "xmm5"
);
@ -5288,7 +5343,7 @@ void ARGBPolynomialRow_AVX2(const uint8* src_argb,
// Tranform ARGB pixels with color table.
void ARGBColorTableRow_X86(uint8* dst_argb, const uint8* table_argb,
int width) {
uintptr_t pixel_temp = 0u;
uintptr_t pixel_temp;
asm volatile (
// 1 pixel loop.
LABELALIGN
@ -5308,10 +5363,10 @@ void ARGBColorTableRow_X86(uint8* dst_argb, const uint8* table_argb,
"mov %b1," MEMACCESS2(-0x1,0) " \n"
"dec %2 \n"
"jg 1b \n"
: "+r"(dst_argb), // %0
"+d"(pixel_temp), // %1
"+r"(width) // %2
: "r"(table_argb) // %3
: "+r"(dst_argb), // %0
"=&d"(pixel_temp), // %1
"+r"(width) // %2
: "r"(table_argb) // %3
: "memory", "cc");
}
#endif // HAS_ARGBCOLORTABLEROW_X86
@ -5319,7 +5374,7 @@ void ARGBColorTableRow_X86(uint8* dst_argb, const uint8* table_argb,
#ifdef HAS_RGBCOLORTABLEROW_X86
// Tranform RGB pixels with color table.
void RGBColorTableRow_X86(uint8* dst_argb, const uint8* table_argb, int width) {
uintptr_t pixel_temp = 0u;
uintptr_t pixel_temp;
asm volatile (
// 1 pixel loop.
LABELALIGN
@ -5336,10 +5391,10 @@ void RGBColorTableRow_X86(uint8* dst_argb, const uint8* table_argb, int width) {
"mov %b1," MEMACCESS2(-0x2,0) " \n"
"dec %2 \n"
"jg 1b \n"
: "+r"(dst_argb), // %0
"+d"(pixel_temp), // %1
"+r"(width) // %2
: "r"(table_argb) // %3
: "+r"(dst_argb), // %0
"=&d"(pixel_temp), // %1
"+r"(width) // %2
: "r"(table_argb) // %3
: "memory", "cc");
}
#endif // HAS_RGBCOLORTABLEROW_X86
@ -5349,8 +5404,8 @@ void RGBColorTableRow_X86(uint8* dst_argb, const uint8* table_argb, int width) {
void ARGBLumaColorTableRow_SSSE3(const uint8* src_argb, uint8* dst_argb,
int width,
const uint8* luma, uint32 lumacoeff) {
uintptr_t pixel_temp = 0u;
uintptr_t table_temp = 0u;
uintptr_t pixel_temp;
uintptr_t table_temp;
asm volatile (
"movd %6,%%xmm3 \n"
"pshufd $0x0,%%xmm3,%%xmm3 \n"
@ -5432,13 +5487,13 @@ void ARGBLumaColorTableRow_SSSE3(const uint8* src_argb, uint8* dst_argb,
"lea " MEMLEA(0x10,3) ",%3 \n"
"sub $0x4,%4 \n"
"jg 1b \n"
: "+d"(pixel_temp), // %0
"+a"(table_temp), // %1
"+r"(src_argb), // %2
"+r"(dst_argb), // %3
"+rm"(width) // %4
: "r"(luma), // %5
"rm"(lumacoeff) // %6
: "=&d"(pixel_temp), // %0
"=&a"(table_temp), // %1
"+r"(src_argb), // %2
"+r"(dst_argb), // %3
"+rm"(width) // %4
: "r"(luma), // %5
"rm"(lumacoeff) // %6
: "memory", "cc", "xmm0", "xmm3", "xmm4", "xmm5"
);
}

View file

@ -375,12 +375,12 @@ void CopyRow_MIPS(const uint8* src, uint8* dst, int count) {
}
#endif // HAS_COPYROW_MIPS
// MIPS DSPR2 functions
// DSPR2 functions
#if !defined(LIBYUV_DISABLE_MIPS) && defined(__mips_dsp) && \
(__mips_dsp_rev >= 2) && \
(_MIPS_SIM == _MIPS_SIM_ABI32) && (__mips_isa_rev < 6)
void SplitUVRow_MIPS_DSPR2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
void SplitUVRow_DSPR2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width) {
__asm__ __volatile__ (
".set push \n"
@ -446,7 +446,7 @@ void SplitUVRow_MIPS_DSPR2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
);
}
void MirrorRow_MIPS_DSPR2(const uint8* src, uint8* dst, int width) {
void MirrorRow_DSPR2(const uint8* src, uint8* dst, int width) {
__asm__ __volatile__ (
".set push \n"
".set noreorder \n"
@ -496,10 +496,10 @@ void MirrorRow_MIPS_DSPR2(const uint8* src, uint8* dst, int width) {
);
}
void MirrorUVRow_MIPS_DSPR2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
void MirrorUVRow_DSPR2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width) {
int x = 0;
int y = 0;
int x;
int y;
__asm__ __volatile__ (
".set push \n"
".set noreorder \n"
@ -579,7 +579,7 @@ void MirrorUVRow_MIPS_DSPR2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
[dst_u] "+r" (dst_u),
[dst_v] "+r" (dst_v),
[x] "=&r" (x),
[y] "+r" (y)
[y] "=&r" (y)
: [width] "r" (width)
: "t0", "t1", "t2", "t3", "t4",
"t5", "t7", "t8", "t9"
@ -653,7 +653,7 @@ void MirrorUVRow_MIPS_DSPR2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
"addu.ph $t1, $t1, $s5 \n"
// TODO(fbarchard): accept yuv conversion constants.
void I422ToARGBRow_MIPS_DSPR2(const uint8* y_buf,
void I422ToARGBRow_DSPR2(const uint8* y_buf,
const uint8* u_buf,
const uint8* v_buf,
uint8* rgb_buf,
@ -716,7 +716,7 @@ void I422ToARGBRow_MIPS_DSPR2(const uint8* y_buf,
}
// Bilinear filter 8x2 -> 8x1
void InterpolateRow_MIPS_DSPR2(uint8* dst_ptr, const uint8* src_ptr,
void InterpolateRow_DSPR2(uint8* dst_ptr, const uint8* src_ptr,
ptrdiff_t src_stride, int dst_width,
int source_y_fraction) {
int y0_fraction = 256 - source_y_fraction;

View file

@ -317,16 +317,11 @@ void I422ToRGB24Row_NEON(const uint8* src_y,
}
#define ARGBTORGB565 \
"vshr.u8 d20, d20, #3 \n" /* B */ \
"vshr.u8 d21, d21, #2 \n" /* G */ \
"vshr.u8 d22, d22, #3 \n" /* R */ \
"vmovl.u8 q8, d20 \n" /* B */ \
"vmovl.u8 q9, d21 \n" /* G */ \
"vmovl.u8 q10, d22 \n" /* R */ \
"vshl.u16 q9, q9, #5 \n" /* G */ \
"vshl.u16 q10, q10, #11 \n" /* R */ \
"vorr q0, q8, q9 \n" /* BG */ \
"vorr q0, q0, q10 \n" /* BGR */
"vshll.u8 q0, d22, #8 \n" /* R */ \
"vshll.u8 q8, d21, #8 \n" /* G */ \
"vshll.u8 q9, d20, #8 \n" /* B */ \
"vsri.16 q0, q8, #5 \n" /* RG */ \
"vsri.16 q0, q9, #11 \n" /* RGB */
void I422ToRGB565Row_NEON(const uint8* src_y,
const uint8* src_u,
@ -359,19 +354,13 @@ void I422ToRGB565Row_NEON(const uint8* src_y,
}
#define ARGBTOARGB1555 \
"vshr.u8 q10, q10, #3 \n" /* B */ \
"vshr.u8 d22, d22, #3 \n" /* R */ \
"vshr.u8 d23, d23, #7 \n" /* A */ \
"vmovl.u8 q8, d20 \n" /* B */ \
"vmovl.u8 q9, d21 \n" /* G */ \
"vmovl.u8 q10, d22 \n" /* R */ \
"vmovl.u8 q11, d23 \n" /* A */ \
"vshl.u16 q9, q9, #5 \n" /* G */ \
"vshl.u16 q10, q10, #10 \n" /* R */ \
"vshl.u16 q11, q11, #15 \n" /* A */ \
"vorr q0, q8, q9 \n" /* BG */ \
"vorr q1, q10, q11 \n" /* RA */ \
"vorr q0, q0, q1 \n" /* BGRA */
"vshll.u8 q0, d23, #8 \n" /* A */ \
"vshll.u8 q8, d22, #8 \n" /* R */ \
"vshll.u8 q9, d21, #8 \n" /* G */ \
"vshll.u8 q10, d20, #8 \n" /* B */ \
"vsri.16 q0, q8, #1 \n" /* AR */ \
"vsri.16 q0, q9, #6 \n" /* ARG */ \
"vsri.16 q0, q10, #11 \n" /* ARGB */
void I422ToARGB1555Row_NEON(const uint8* src_y,
const uint8* src_u,
@ -1374,55 +1363,6 @@ void ARGBToUV444Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
);
}
// 16x1 pixels -> 8x1. width is number of argb pixels. e.g. 16.
void ARGBToUV422Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
int width) {
asm volatile (
"vmov.s16 q10, #112 / 2 \n" // UB / VR 0.875 coefficient
"vmov.s16 q11, #74 / 2 \n" // UG -0.5781 coefficient
"vmov.s16 q12, #38 / 2 \n" // UR -0.2969 coefficient
"vmov.s16 q13, #18 / 2 \n" // VB -0.1406 coefficient
"vmov.s16 q14, #94 / 2 \n" // VG -0.7344 coefficient
"vmov.u16 q15, #0x8080 \n" // 128.5
"1: \n"
MEMACCESS(0)
"vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels.
MEMACCESS(0)
"vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 ARGB pixels.
"vpaddl.u8 q0, q0 \n" // B 16 bytes -> 8 shorts.
"vpaddl.u8 q1, q1 \n" // G 16 bytes -> 8 shorts.
"vpaddl.u8 q2, q2 \n" // R 16 bytes -> 8 shorts.
"subs %3, %3, #16 \n" // 16 processed per loop.
"vmul.s16 q8, q0, q10 \n" // B
"vmls.s16 q8, q1, q11 \n" // G
"vmls.s16 q8, q2, q12 \n" // R
"vadd.u16 q8, q8, q15 \n" // +128 -> unsigned
"vmul.s16 q9, q2, q10 \n" // R
"vmls.s16 q9, q1, q14 \n" // G
"vmls.s16 q9, q0, q13 \n" // B
"vadd.u16 q9, q9, q15 \n" // +128 -> unsigned
"vqshrn.u16 d0, q8, #8 \n" // 16 bit to 8 bit U
"vqshrn.u16 d1, q9, #8 \n" // 16 bit to 8 bit V
MEMACCESS(1)
"vst1.8 {d0}, [%1]! \n" // store 8 pixels U.
MEMACCESS(2)
"vst1.8 {d1}, [%2]! \n" // store 8 pixels V.
"bgt 1b \n"
: "+r"(src_argb), // %0
"+r"(dst_u), // %1
"+r"(dst_v), // %2
"+r"(width) // %3
:
: "cc", "memory", "q0", "q1", "q2", "q3",
"q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
);
}
// 32x1 pixels -> 8x1. width is number of argb pixels. e.g. 32.
void ARGBToUV411Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
int width) {

View file

@ -323,8 +323,8 @@ void I422ToRGB24Row_NEON(const uint8* src_y,
#define ARGBTORGB565 \
"shll v0.8h, v22.8b, #8 \n" /* R */ \
"shll v20.8h, v20.8b, #8 \n" /* B */ \
"shll v21.8h, v21.8b, #8 \n" /* G */ \
"shll v20.8h, v20.8b, #8 \n" /* B */ \
"sri v0.8h, v21.8h, #5 \n" /* RG */ \
"sri v0.8h, v20.8h, #11 \n" /* RGB */
@ -363,8 +363,8 @@ void I422ToRGB565Row_NEON(const uint8* src_y,
#define ARGBTOARGB1555 \
"shll v0.8h, v23.8b, #8 \n" /* A */ \
"shll v22.8h, v22.8b, #8 \n" /* R */ \
"shll v20.8h, v20.8b, #8 \n" /* B */ \
"shll v21.8h, v21.8b, #8 \n" /* G */ \
"shll v20.8h, v20.8b, #8 \n" /* B */ \
"sri v0.8h, v22.8h, #1 \n" /* AR */ \
"sri v0.8h, v21.8h, #6 \n" /* ARG */ \
"sri v0.8h, v20.8h, #11 \n" /* ARGB */
@ -1477,50 +1477,6 @@ void ARGBToUV444Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
"movi v24.8h, #47, lsl #0 \n" /* VG coefficient (-0.7344) / 2 */ \
"movi v25.16b, #0x80 \n" /* 128.5 (0x8080 in 16-bit) */
// 16x1 pixels -> 8x1. width is number of argb pixels. e.g. 16.
#ifdef HAS_ARGBTOUV422ROW_NEON
void ARGBToUV422Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
int width) {
asm volatile (
RGBTOUV_SETUP_REG
"1: \n"
MEMACCESS(0)
"ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 16 pixels.
"uaddlp v0.8h, v0.16b \n" // B 16 bytes -> 8 shorts.
"uaddlp v1.8h, v1.16b \n" // G 16 bytes -> 8 shorts.
"uaddlp v2.8h, v2.16b \n" // R 16 bytes -> 8 shorts.
"subs %w3, %w3, #16 \n" // 16 processed per loop.
"mul v3.8h, v0.8h, v20.8h \n" // B
"mls v3.8h, v1.8h, v21.8h \n" // G
"mls v3.8h, v2.8h, v22.8h \n" // R
"add v3.8h, v3.8h, v25.8h \n" // +128 -> unsigned
"mul v4.8h, v2.8h, v20.8h \n" // R
"mls v4.8h, v1.8h, v24.8h \n" // G
"mls v4.8h, v0.8h, v23.8h \n" // B
"add v4.8h, v4.8h, v25.8h \n" // +128 -> unsigned
"uqshrn v0.8b, v3.8h, #8 \n" // 16 bit to 8 bit U
"uqshrn v1.8b, v4.8h, #8 \n" // 16 bit to 8 bit V
MEMACCESS(1)
"st1 {v0.8b}, [%1], #8 \n" // store 8 pixels U.
MEMACCESS(2)
"st1 {v1.8b}, [%2], #8 \n" // store 8 pixels V.
"b.gt 1b \n"
: "+r"(src_argb), // %0
"+r"(dst_u), // %1
"+r"(dst_v), // %2
"+r"(width) // %3
:
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
"v20", "v21", "v22", "v23", "v24", "v25"
);
}
#endif // HAS_ARGBTOUV422ROW_NEON
// 32x1 pixels -> 8x1. width is number of argb pixels. e.g. 32.
#ifdef HAS_ARGBTOUV411ROW_NEON
void ARGBToUV411Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,

View file

@ -1505,7 +1505,7 @@ void ARGBToUVJRow_SSSE3(const uint8* src_argb0, int src_stride_argb,
pmaddubsw xmm3, xmm6
phaddw xmm0, xmm2
phaddw xmm1, xmm3
paddw xmm0, xmm5 // +.5 rounding -> unsigned
paddw xmm0, xmm5 // +.5 rounding -> unsigned
paddw xmm1, xmm5
psraw xmm0, 8
psraw xmm1, 8
@ -1590,6 +1590,73 @@ void ARGBToUVRow_AVX2(const uint8* src_argb0, int src_stride_argb,
}
#endif // HAS_ARGBTOUVROW_AVX2
#ifdef HAS_ARGBTOUVJROW_AVX2
__declspec(naked)
void ARGBToUVJRow_AVX2(const uint8* src_argb0, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width) {
__asm {
push esi
push edi
mov eax, [esp + 8 + 4] // src_argb
mov esi, [esp + 8 + 8] // src_stride_argb
mov edx, [esp + 8 + 12] // dst_u
mov edi, [esp + 8 + 16] // dst_v
mov ecx, [esp + 8 + 20] // width
vbroadcastf128 ymm5, xmmword ptr kAddUV128
vbroadcastf128 ymm6, xmmword ptr kARGBToV
vbroadcastf128 ymm7, xmmword ptr kARGBToU
sub edi, edx // stride from u to v
convertloop:
/* step 1 - subsample 32x2 argb pixels to 16x1 */
vmovdqu ymm0, [eax]
vmovdqu ymm1, [eax + 32]
vmovdqu ymm2, [eax + 64]
vmovdqu ymm3, [eax + 96]
vpavgb ymm0, ymm0, [eax + esi]
vpavgb ymm1, ymm1, [eax + esi + 32]
vpavgb ymm2, ymm2, [eax + esi + 64]
vpavgb ymm3, ymm3, [eax + esi + 96]
lea eax, [eax + 128]
vshufps ymm4, ymm0, ymm1, 0x88
vshufps ymm0, ymm0, ymm1, 0xdd
vpavgb ymm0, ymm0, ymm4 // mutated by vshufps
vshufps ymm4, ymm2, ymm3, 0x88
vshufps ymm2, ymm2, ymm3, 0xdd
vpavgb ymm2, ymm2, ymm4 // mutated by vshufps
// step 2 - convert to U and V
// from here down is very similar to Y code except
// instead of 32 different pixels, its 16 pixels of U and 16 of V
vpmaddubsw ymm1, ymm0, ymm7 // U
vpmaddubsw ymm3, ymm2, ymm7
vpmaddubsw ymm0, ymm0, ymm6 // V
vpmaddubsw ymm2, ymm2, ymm6
vphaddw ymm1, ymm1, ymm3 // mutates
vphaddw ymm0, ymm0, ymm2
vpaddw ymm1, ymm1, ymm5 // +.5 rounding -> unsigned
vpaddw ymm0, ymm0, ymm5
vpsraw ymm1, ymm1, 8
vpsraw ymm0, ymm0, 8
vpacksswb ymm0, ymm1, ymm0 // mutates
vpermq ymm0, ymm0, 0xd8 // For vpacksswb
vpshufb ymm0, ymm0, ymmword ptr kShufARGBToUV_AVX // for vshufps/vphaddw
// step 3 - store 16 U and 16 V values
vextractf128 [edx], ymm0, 0 // U
vextractf128 [edx + edi], ymm0, 1 // V
lea edx, [edx + 16]
sub ecx, 32
jg convertloop
pop edi
pop esi
vzeroupper
ret
}
}
#endif // HAS_ARGBTOUVJROW_AVX2
__declspec(naked)
void ARGBToUV444Row_SSSE3(const uint8* src_argb0,
uint8* dst_u, uint8* dst_v, int width) {
@ -1647,64 +1714,6 @@ void ARGBToUV444Row_SSSE3(const uint8* src_argb0,
}
}
__declspec(naked)
void ARGBToUV422Row_SSSE3(const uint8* src_argb0,
uint8* dst_u, uint8* dst_v, int width) {
__asm {
push edi
mov eax, [esp + 4 + 4] // src_argb
mov edx, [esp + 4 + 8] // dst_u
mov edi, [esp + 4 + 12] // dst_v
mov ecx, [esp + 4 + 16] // width
movdqa xmm5, xmmword ptr kAddUV128
movdqa xmm6, xmmword ptr kARGBToV
movdqa xmm7, xmmword ptr kARGBToU
sub edi, edx // stride from u to v
convertloop:
/* step 1 - subsample 16x2 argb pixels to 8x1 */
movdqu xmm0, [eax]
movdqu xmm1, [eax + 16]
movdqu xmm2, [eax + 32]
movdqu xmm3, [eax + 48]
lea eax, [eax + 64]
movdqa xmm4, xmm0
shufps xmm0, xmm1, 0x88
shufps xmm4, xmm1, 0xdd
pavgb xmm0, xmm4
movdqa xmm4, xmm2
shufps xmm2, xmm3, 0x88
shufps xmm4, xmm3, 0xdd
pavgb xmm2, xmm4
// step 2 - convert to U and V
// from here down is very similar to Y code except
// instead of 16 different pixels, its 8 pixels of U and 8 of V
movdqa xmm1, xmm0
movdqa xmm3, xmm2
pmaddubsw xmm0, xmm7 // U
pmaddubsw xmm2, xmm7
pmaddubsw xmm1, xmm6 // V
pmaddubsw xmm3, xmm6
phaddw xmm0, xmm2
phaddw xmm1, xmm3
psraw xmm0, 8
psraw xmm1, 8
packsswb xmm0, xmm1
paddb xmm0, xmm5 // -> unsigned
// step 3 - store 8 U and 8 V values
movlps qword ptr [edx], xmm0 // U
movhps qword ptr [edx + edi], xmm0 // V
lea edx, [edx + 8]
sub ecx, 16
jg convertloop
pop edi
ret
}
}
__declspec(naked)
void BGRAToUVRow_SSSE3(const uint8* src_argb0, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width) {
@ -3154,7 +3163,7 @@ void MirrorRow_AVX2(const uint8* src, uint8* dst, int width) {
}
#endif // HAS_MIRRORROW_AVX2
#ifdef HAS_MIRRORROW_UV_SSSE3
#ifdef HAS_MIRRORUVROW_SSSE3
// Shuffle table for reversing the bytes of UV channels.
static const uvec8 kShuffleMirrorUV = {
14u, 12u, 10u, 8u, 6u, 4u, 2u, 0u, 15u, 13u, 11u, 9u, 7u, 5u, 3u, 1u
@ -3187,7 +3196,7 @@ void MirrorUVRow_SSSE3(const uint8* src, uint8* dst_u, uint8* dst_v,
ret
}
}
#endif // HAS_MIRRORROW_UV_SSSE3
#endif // HAS_MIRRORUVROW_SSSE3
#ifdef HAS_ARGBMIRRORROW_SSE2
__declspec(naked)

View file

@ -85,12 +85,12 @@ static void ScalePlaneDown2(int src_width, int src_height,
}
}
#endif
#if defined(HAS_SCALEROWDOWN2_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(src_ptr, 4) &&
#if defined(HAS_SCALEROWDOWN2_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(src_ptr, 4) &&
IS_ALIGNED(src_stride, 4) && IS_ALIGNED(row_stride, 4) &&
IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) {
ScaleRowDown2 = filtering ?
ScaleRowDown2Box_MIPS_DSPR2 : ScaleRowDown2_MIPS_DSPR2;
ScaleRowDown2Box_DSPR2 : ScaleRowDown2_DSPR2;
}
#endif
@ -135,12 +135,12 @@ static void ScalePlaneDown2_16(int src_width, int src_height,
ScaleRowDown2Box_16_SSE2);
}
#endif
#if defined(HAS_SCALEROWDOWN2_16_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(src_ptr, 4) &&
#if defined(HAS_SCALEROWDOWN2_16_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(src_ptr, 4) &&
IS_ALIGNED(src_stride, 4) && IS_ALIGNED(row_stride, 4) &&
IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) {
ScaleRowDown2 = filtering ?
ScaleRowDown2Box_16_MIPS_DSPR2 : ScaleRowDown2_16_MIPS_DSPR2;
ScaleRowDown2Box_16_DSPR2 : ScaleRowDown2_16_DSPR2;
}
#endif
@ -200,12 +200,12 @@ static void ScalePlaneDown4(int src_width, int src_height,
}
}
#endif
#if defined(HAS_SCALEROWDOWN4_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(row_stride, 4) &&
#if defined(HAS_SCALEROWDOWN4_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(row_stride, 4) &&
IS_ALIGNED(src_ptr, 4) && IS_ALIGNED(src_stride, 4) &&
IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) {
ScaleRowDown4 = filtering ?
ScaleRowDown4Box_MIPS_DSPR2 : ScaleRowDown4_MIPS_DSPR2;
ScaleRowDown4Box_DSPR2 : ScaleRowDown4_DSPR2;
}
#endif
@ -245,12 +245,12 @@ static void ScalePlaneDown4_16(int src_width, int src_height,
ScaleRowDown4_16_SSE2;
}
#endif
#if defined(HAS_SCALEROWDOWN4_16_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(row_stride, 4) &&
#if defined(HAS_SCALEROWDOWN4_16_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(row_stride, 4) &&
IS_ALIGNED(src_ptr, 4) && IS_ALIGNED(src_stride, 4) &&
IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) {
ScaleRowDown4 = filtering ?
ScaleRowDown4Box_16_MIPS_DSPR2 : ScaleRowDown4_16_MIPS_DSPR2;
ScaleRowDown4Box_16_DSPR2 : ScaleRowDown4_16_DSPR2;
}
#endif
@ -325,16 +325,16 @@ static void ScalePlaneDown34(int src_width, int src_height,
}
}
#endif
#if defined(HAS_SCALEROWDOWN34_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) && (dst_width % 24 == 0) &&
#if defined(HAS_SCALEROWDOWN34_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) && (dst_width % 24 == 0) &&
IS_ALIGNED(src_ptr, 4) && IS_ALIGNED(src_stride, 4) &&
IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) {
if (!filtering) {
ScaleRowDown34_0 = ScaleRowDown34_MIPS_DSPR2;
ScaleRowDown34_1 = ScaleRowDown34_MIPS_DSPR2;
ScaleRowDown34_0 = ScaleRowDown34_DSPR2;
ScaleRowDown34_1 = ScaleRowDown34_DSPR2;
} else {
ScaleRowDown34_0 = ScaleRowDown34_0_Box_MIPS_DSPR2;
ScaleRowDown34_1 = ScaleRowDown34_1_Box_MIPS_DSPR2;
ScaleRowDown34_0 = ScaleRowDown34_0_Box_DSPR2;
ScaleRowDown34_1 = ScaleRowDown34_1_Box_DSPR2;
}
}
#endif
@ -404,16 +404,16 @@ static void ScalePlaneDown34_16(int src_width, int src_height,
}
}
#endif
#if defined(HAS_SCALEROWDOWN34_16_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) && (dst_width % 24 == 0) &&
#if defined(HAS_SCALEROWDOWN34_16_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) && (dst_width % 24 == 0) &&
IS_ALIGNED(src_ptr, 4) && IS_ALIGNED(src_stride, 4) &&
IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) {
if (!filtering) {
ScaleRowDown34_0 = ScaleRowDown34_16_MIPS_DSPR2;
ScaleRowDown34_1 = ScaleRowDown34_16_MIPS_DSPR2;
ScaleRowDown34_0 = ScaleRowDown34_16_DSPR2;
ScaleRowDown34_1 = ScaleRowDown34_16_DSPR2;
} else {
ScaleRowDown34_0 = ScaleRowDown34_0_Box_16_MIPS_DSPR2;
ScaleRowDown34_1 = ScaleRowDown34_1_Box_16_MIPS_DSPR2;
ScaleRowDown34_0 = ScaleRowDown34_0_Box_16_DSPR2;
ScaleRowDown34_1 = ScaleRowDown34_1_Box_16_DSPR2;
}
}
#endif
@ -517,16 +517,16 @@ static void ScalePlaneDown38(int src_width, int src_height,
}
}
#endif
#if defined(HAS_SCALEROWDOWN38_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) && (dst_width % 12 == 0) &&
#if defined(HAS_SCALEROWDOWN38_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) && (dst_width % 12 == 0) &&
IS_ALIGNED(src_ptr, 4) && IS_ALIGNED(src_stride, 4) &&
IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) {
if (!filtering) {
ScaleRowDown38_3 = ScaleRowDown38_MIPS_DSPR2;
ScaleRowDown38_2 = ScaleRowDown38_MIPS_DSPR2;
ScaleRowDown38_3 = ScaleRowDown38_DSPR2;
ScaleRowDown38_2 = ScaleRowDown38_DSPR2;
} else {
ScaleRowDown38_3 = ScaleRowDown38_3_Box_MIPS_DSPR2;
ScaleRowDown38_2 = ScaleRowDown38_2_Box_MIPS_DSPR2;
ScaleRowDown38_3 = ScaleRowDown38_3_Box_DSPR2;
ScaleRowDown38_2 = ScaleRowDown38_2_Box_DSPR2;
}
}
#endif
@ -595,16 +595,16 @@ static void ScalePlaneDown38_16(int src_width, int src_height,
}
}
#endif
#if defined(HAS_SCALEROWDOWN38_16_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) && (dst_width % 12 == 0) &&
#if defined(HAS_SCALEROWDOWN38_16_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) && (dst_width % 12 == 0) &&
IS_ALIGNED(src_ptr, 4) && IS_ALIGNED(src_stride, 4) &&
IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) {
if (!filtering) {
ScaleRowDown38_3 = ScaleRowDown38_16_MIPS_DSPR2;
ScaleRowDown38_2 = ScaleRowDown38_16_MIPS_DSPR2;
ScaleRowDown38_3 = ScaleRowDown38_16_DSPR2;
ScaleRowDown38_2 = ScaleRowDown38_16_DSPR2;
} else {
ScaleRowDown38_3 = ScaleRowDown38_3_Box_16_MIPS_DSPR2;
ScaleRowDown38_2 = ScaleRowDown38_2_Box_16_MIPS_DSPR2;
ScaleRowDown38_3 = ScaleRowDown38_3_Box_16_DSPR2;
ScaleRowDown38_2 = ScaleRowDown38_2_Box_16_DSPR2;
}
}
#endif
@ -659,7 +659,6 @@ static void ScaleAddCols2_C(int dst_width, int boxheight, int x, int dx,
int i;
int scaletbl[2];
int minboxwidth = dx >> 16;
int* scaleptr = scaletbl - minboxwidth;
int boxwidth;
scaletbl[0] = 65536 / (MIN1(minboxwidth) * boxheight);
scaletbl[1] = 65536 / (MIN1(minboxwidth + 1) * boxheight);
@ -667,7 +666,8 @@ static void ScaleAddCols2_C(int dst_width, int boxheight, int x, int dx,
int ix = x >> 16;
x += dx;
boxwidth = MIN1((x >> 16) - ix);
*dst_ptr++ = SumPixels(boxwidth, src_ptr + ix) * scaleptr[boxwidth] >> 16;
*dst_ptr++ = SumPixels(boxwidth, src_ptr + ix) *
scaletbl[boxwidth - minboxwidth] >> 16;
}
}
@ -676,7 +676,6 @@ static void ScaleAddCols2_16_C(int dst_width, int boxheight, int x, int dx,
int i;
int scaletbl[2];
int minboxwidth = dx >> 16;
int* scaleptr = scaletbl - minboxwidth;
int boxwidth;
scaletbl[0] = 65536 / (MIN1(minboxwidth) * boxheight);
scaletbl[1] = 65536 / (MIN1(minboxwidth + 1) * boxheight);
@ -684,8 +683,8 @@ static void ScaleAddCols2_16_C(int dst_width, int boxheight, int x, int dx,
int ix = x >> 16;
x += dx;
boxwidth = MIN1((x >> 16) - ix);
*dst_ptr++ =
SumPixels_16(boxwidth, src_ptr + ix) * scaleptr[boxwidth] >> 16;
*dst_ptr++ = SumPixels_16(boxwidth, src_ptr + ix) *
scaletbl[boxwidth - minboxwidth] >> 16;
}
}
@ -899,11 +898,11 @@ void ScalePlaneBilinearDown(int src_width, int src_height,
}
}
#endif
#if defined(HAS_INTERPOLATEROW_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2)) {
InterpolateRow = InterpolateRow_Any_MIPS_DSPR2;
#if defined(HAS_INTERPOLATEROW_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2)) {
InterpolateRow = InterpolateRow_Any_DSPR2;
if (IS_ALIGNED(src_width, 4)) {
InterpolateRow = InterpolateRow_MIPS_DSPR2;
InterpolateRow = InterpolateRow_DSPR2;
}
}
#endif
@ -1003,11 +1002,11 @@ void ScalePlaneBilinearDown_16(int src_width, int src_height,
}
}
#endif
#if defined(HAS_INTERPOLATEROW_16_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2)) {
InterpolateRow = InterpolateRow_Any_16_MIPS_DSPR2;
#if defined(HAS_INTERPOLATEROW_16_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2)) {
InterpolateRow = InterpolateRow_Any_16_DSPR2;
if (IS_ALIGNED(src_width, 4)) {
InterpolateRow = InterpolateRow_16_MIPS_DSPR2;
InterpolateRow = InterpolateRow_16_DSPR2;
}
}
#endif
@ -1088,11 +1087,11 @@ void ScalePlaneBilinearUp(int src_width, int src_height,
}
}
#endif
#if defined(HAS_INTERPOLATEROW_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2)) {
InterpolateRow = InterpolateRow_Any_MIPS_DSPR2;
#if defined(HAS_INTERPOLATEROW_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2)) {
InterpolateRow = InterpolateRow_Any_DSPR2;
if (IS_ALIGNED(dst_width, 4)) {
InterpolateRow = InterpolateRow_MIPS_DSPR2;
InterpolateRow = InterpolateRow_DSPR2;
}
}
#endif
@ -1227,11 +1226,11 @@ void ScalePlaneBilinearUp_16(int src_width, int src_height,
}
}
#endif
#if defined(HAS_INTERPOLATEROW_16_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2)) {
InterpolateRow = InterpolateRow_Any_16_MIPS_DSPR2;
#if defined(HAS_INTERPOLATEROW_16_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2)) {
InterpolateRow = InterpolateRow_Any_16_DSPR2;
if (IS_ALIGNED(dst_width, 4)) {
InterpolateRow = InterpolateRow_16_MIPS_DSPR2;
InterpolateRow = InterpolateRow_16_DSPR2;
}
}
#endif

View file

@ -55,12 +55,29 @@ CANY(ScaleARGBFilterCols_Any_NEON, ScaleARGBFilterCols_NEON,
dst_ptr + n * BPP, r); \
}
// Fixed scale down for odd source width. Used by I420Blend subsampling.
// Since dst_width is (width + 1) / 2, this function scales one less pixel
// and copies the last pixel.
#define SDODD(NAMEANY, SCALEROWDOWN_SIMD, SCALEROWDOWN_C, FACTOR, BPP, MASK) \
void NAMEANY(const uint8* src_ptr, ptrdiff_t src_stride, \
uint8* dst_ptr, int dst_width) { \
int r = (int)((unsigned int)(dst_width - 1) % (MASK + 1)); \
int n = dst_width - r; \
if (n > 0) { \
SCALEROWDOWN_SIMD(src_ptr, src_stride, dst_ptr, n); \
} \
SCALEROWDOWN_C(src_ptr + (n * FACTOR) * BPP, src_stride, \
dst_ptr + n * BPP, r); \
}
#ifdef HAS_SCALEROWDOWN2_SSSE3
SDANY(ScaleRowDown2_Any_SSSE3, ScaleRowDown2_SSSE3, ScaleRowDown2_C, 2, 1, 15)
SDANY(ScaleRowDown2Linear_Any_SSSE3, ScaleRowDown2Linear_SSSE3,
ScaleRowDown2Linear_C, 2, 1, 15)
SDANY(ScaleRowDown2Box_Any_SSSE3, ScaleRowDown2Box_SSSE3, ScaleRowDown2Box_C,
2, 1, 15)
SDODD(ScaleRowDown2Box_Odd_SSSE3, ScaleRowDown2Box_SSSE3,
ScaleRowDown2Box_Odd_C, 2, 1, 15)
#endif
#ifdef HAS_SCALEROWDOWN2_AVX2
SDANY(ScaleRowDown2_Any_AVX2, ScaleRowDown2_AVX2, ScaleRowDown2_C, 2, 1, 31)
@ -68,6 +85,8 @@ SDANY(ScaleRowDown2Linear_Any_AVX2, ScaleRowDown2Linear_AVX2,
ScaleRowDown2Linear_C, 2, 1, 31)
SDANY(ScaleRowDown2Box_Any_AVX2, ScaleRowDown2Box_AVX2, ScaleRowDown2Box_C,
2, 1, 31)
SDODD(ScaleRowDown2Box_Odd_AVX2, ScaleRowDown2Box_AVX2, ScaleRowDown2Box_Odd_C,
2, 1, 31)
#endif
#ifdef HAS_SCALEROWDOWN2_NEON
SDANY(ScaleRowDown2_Any_NEON, ScaleRowDown2_NEON, ScaleRowDown2_C, 2, 1, 15)
@ -75,6 +94,8 @@ SDANY(ScaleRowDown2Linear_Any_NEON, ScaleRowDown2Linear_NEON,
ScaleRowDown2Linear_C, 2, 1, 15)
SDANY(ScaleRowDown2Box_Any_NEON, ScaleRowDown2Box_NEON,
ScaleRowDown2Box_C, 2, 1, 15)
SDODD(ScaleRowDown2Box_Odd_NEON, ScaleRowDown2Box_NEON,
ScaleRowDown2Box_Odd_C, 2, 1, 15)
#endif
#ifdef HAS_SCALEROWDOWN4_SSSE3
SDANY(ScaleRowDown4_Any_SSSE3, ScaleRowDown4_SSSE3, ScaleRowDown4_C, 4, 1, 7)

View file

@ -234,12 +234,12 @@ static void ScaleARGBBilinearDown(int src_width, int src_height,
}
}
#endif
#if defined(HAS_INTERPOLATEROW_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) &&
#if defined(HAS_INTERPOLATEROW_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) &&
IS_ALIGNED(src_argb, 4) && IS_ALIGNED(src_stride, 4)) {
InterpolateRow = InterpolateRow_Any_MIPS_DSPR2;
InterpolateRow = InterpolateRow_Any_DSPR2;
if (IS_ALIGNED(clip_src_width, 4)) {
InterpolateRow = InterpolateRow_MIPS_DSPR2;
InterpolateRow = InterpolateRow_DSPR2;
}
}
#endif
@ -324,10 +324,10 @@ static void ScaleARGBBilinearUp(int src_width, int src_height,
}
}
#endif
#if defined(HAS_INTERPOLATEROW_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) &&
#if defined(HAS_INTERPOLATEROW_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) &&
IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride, 4)) {
InterpolateRow = InterpolateRow_MIPS_DSPR2;
InterpolateRow = InterpolateRow_DSPR2;
}
#endif
if (src_width >= 32768) {
@ -465,13 +465,13 @@ static void ScaleYUVToARGBBilinearUp(int src_width, int src_height,
}
}
#endif
#if defined(HAS_I422TOARGBROW_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(src_width, 4) &&
#if defined(HAS_I422TOARGBROW_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(src_width, 4) &&
IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) &&
IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) &&
IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) &&
IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) {
I422ToARGBRow = I422ToARGBRow_MIPS_DSPR2;
I422ToARGBRow = I422ToARGBRow_DSPR2;
}
#endif
@ -502,10 +502,10 @@ static void ScaleYUVToARGBBilinearUp(int src_width, int src_height,
}
}
#endif
#if defined(HAS_INTERPOLATEROW_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) &&
#if defined(HAS_INTERPOLATEROW_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) &&
IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) {
InterpolateRow = InterpolateRow_MIPS_DSPR2;
InterpolateRow = InterpolateRow_DSPR2;
}
#endif
@ -835,7 +835,6 @@ int YUVToARGBScaleClip(const uint8* src_y, int src_stride_y,
int dst_width, int dst_height,
int clip_x, int clip_y, int clip_width, int clip_height,
enum FilterMode filtering) {
uint8* argb_buffer = (uint8*)malloc(src_width * src_height * 4);
int r;
I420ToARGB(src_y, src_stride_y,

View file

@ -103,6 +103,28 @@ void ScaleRowDown2Box_C(const uint8* src_ptr, ptrdiff_t src_stride,
}
}
void ScaleRowDown2Box_Odd_C(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width) {
const uint8* s = src_ptr;
const uint8* t = src_ptr + src_stride;
int x;
dst_width -= 1;
for (x = 0; x < dst_width - 1; x += 2) {
dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2;
dst[1] = (s[2] + s[3] + t[2] + t[3] + 2) >> 2;
dst += 2;
s += 4;
t += 4;
}
if (dst_width & 1) {
dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2;
dst += 1;
s += 2;
t += 2;
}
dst[0] = (s[0] + t[0] + 1) >> 1;
}
void ScaleRowDown2Box_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
uint16* dst, int dst_width) {
const uint16* s = src_ptr;
@ -900,13 +922,13 @@ void ScalePlaneVertical(int src_height,
}
}
#endif
#if defined(HAS_INTERPOLATEROW_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) &&
#if defined(HAS_INTERPOLATEROW_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) &&
IS_ALIGNED(src_argb, 4) && IS_ALIGNED(src_stride, 4) &&
IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride, 4)) {
InterpolateRow = InterpolateRow_Any_MIPS_DSPR2;
InterpolateRow = InterpolateRow_Any_DSPR2;
if (IS_ALIGNED(dst_width_bytes, 4)) {
InterpolateRow = InterpolateRow_MIPS_DSPR2;
InterpolateRow = InterpolateRow_DSPR2;
}
}
#endif
@ -974,13 +996,13 @@ void ScalePlaneVertical_16(int src_height,
}
}
#endif
#if defined(HAS_INTERPOLATEROW_16_MIPS_DSPR2)
if (TestCpuFlag(kCpuHasMIPS_DSPR2) &&
#if defined(HAS_INTERPOLATEROW_16_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) &&
IS_ALIGNED(src_argb, 4) && IS_ALIGNED(src_stride, 4) &&
IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride, 4)) {
InterpolateRow = InterpolateRow_Any_16_MIPS_DSPR2;
InterpolateRow = InterpolateRow_Any_16_DSPR2;
if (IS_ALIGNED(dst_width_bytes, 4)) {
InterpolateRow = InterpolateRow_16_MIPS_DSPR2;
InterpolateRow = InterpolateRow_16_DSPR2;
}
}
#endif

View file

@ -316,7 +316,7 @@ void ScaleRowDown4_SSSE3(const uint8* src_ptr, ptrdiff_t src_stride,
void ScaleRowDown4Box_SSSE3(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst_ptr, int dst_width) {
intptr_t stridex3 = 0;
intptr_t stridex3;
asm volatile (
"pcmpeqb %%xmm4,%%xmm4 \n"
"psrlw $0xf,%%xmm4 \n"
@ -361,7 +361,7 @@ void ScaleRowDown4Box_SSSE3(const uint8* src_ptr, ptrdiff_t src_stride,
: "+r"(src_ptr), // %0
"+r"(dst_ptr), // %1
"+r"(dst_width), // %2
"+r"(stridex3) // %3
"=&r"(stridex3) // %3
: "r"((intptr_t)(src_stride)) // %4
: "memory", "cc", NACL_R14
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"
@ -824,7 +824,7 @@ void ScaleAddRow_AVX2(const uint8* src_ptr, uint16* dst_ptr, int src_width) {
// Bilinear column filtering. SSSE3 version.
void ScaleFilterCols_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
int dst_width, int x, int dx) {
intptr_t x0 = 0, x1 = 0, temp_pixel = 0;
intptr_t x0, x1, temp_pixel;
asm volatile (
"movd %6,%%xmm2 \n"
"movd %7,%%xmm3 \n"
@ -880,14 +880,14 @@ void ScaleFilterCols_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
"movd %%xmm0,%k2 \n"
"mov %b2," MEMACCESS(0) " \n"
"99: \n"
: "+r"(dst_ptr), // %0
"+r"(src_ptr), // %1
"+a"(temp_pixel), // %2
"+r"(x0), // %3
"+r"(x1), // %4
"+rm"(dst_width) // %5
: "rm"(x), // %6
"rm"(dx) // %7
: "+r"(dst_ptr), // %0
"+r"(src_ptr), // %1
"=&a"(temp_pixel), // %2
"=&r"(x0), // %3
"=&r"(x1), // %4
"+rm"(dst_width) // %5
: "rm"(x), // %6
"rm"(dx) // %7
: "memory", "cc", NACL_R14
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"
);
@ -998,7 +998,7 @@ void ScaleARGBRowDown2Box_SSE2(const uint8* src_argb,
void ScaleARGBRowDownEven_SSE2(const uint8* src_argb, ptrdiff_t src_stride,
int src_stepx, uint8* dst_argb, int dst_width) {
intptr_t src_stepx_x4 = (intptr_t)(src_stepx);
intptr_t src_stepx_x12 = 0;
intptr_t src_stepx_x12;
asm volatile (
"lea " MEMLEA3(0x00,1,4) ",%1 \n"
"lea " MEMLEA4(0x00,1,1,2) ",%4 \n"
@ -1016,11 +1016,11 @@ void ScaleARGBRowDownEven_SSE2(const uint8* src_argb, ptrdiff_t src_stride,
"lea " MEMLEA(0x10,2) ",%2 \n"
"sub $0x4,%3 \n"
"jg 1b \n"
: "+r"(src_argb), // %0
"+r"(src_stepx_x4), // %1
"+r"(dst_argb), // %2
"+r"(dst_width), // %3
"+r"(src_stepx_x12) // %4
: "+r"(src_argb), // %0
"+r"(src_stepx_x4), // %1
"+r"(dst_argb), // %2
"+r"(dst_width), // %3
"=&r"(src_stepx_x12) // %4
:: "memory", "cc", NACL_R14
"xmm0", "xmm1", "xmm2", "xmm3"
);
@ -1032,7 +1032,7 @@ void ScaleARGBRowDownEvenBox_SSE2(const uint8* src_argb,
ptrdiff_t src_stride, int src_stepx,
uint8* dst_argb, int dst_width) {
intptr_t src_stepx_x4 = (intptr_t)(src_stepx);
intptr_t src_stepx_x12 = 0;
intptr_t src_stepx_x12;
intptr_t row1 = (intptr_t)(src_stride);
asm volatile (
"lea " MEMLEA3(0x00,1,4) ",%1 \n"
@ -1061,12 +1061,12 @@ void ScaleARGBRowDownEvenBox_SSE2(const uint8* src_argb,
"lea " MEMLEA(0x10,2) ",%2 \n"
"sub $0x4,%3 \n"
"jg 1b \n"
: "+r"(src_argb), // %0
"+r"(src_stepx_x4), // %1
"+r"(dst_argb), // %2
"+rm"(dst_width), // %3
"+r"(src_stepx_x12), // %4
"+r"(row1) // %5
: "+r"(src_argb), // %0
"+r"(src_stepx_x4), // %1
"+r"(dst_argb), // %2
"+rm"(dst_width), // %3
"=&r"(src_stepx_x12), // %4
"+r"(row1) // %5
:: "memory", "cc", NACL_R14
"xmm0", "xmm1", "xmm2", "xmm3"
);
@ -1074,7 +1074,7 @@ void ScaleARGBRowDownEvenBox_SSE2(const uint8* src_argb,
void ScaleARGBCols_SSE2(uint8* dst_argb, const uint8* src_argb,
int dst_width, int x, int dx) {
intptr_t x0 = 0, x1 = 0;
intptr_t x0, x1;
asm volatile (
"movd %5,%%xmm2 \n"
"movd %6,%%xmm3 \n"
@ -1127,8 +1127,8 @@ void ScaleARGBCols_SSE2(uint8* dst_argb, const uint8* src_argb,
MEMOPREG(movd,0x00,3,0,4,xmm0) // movd (%3,%0,4),%%xmm0
"movd %%xmm0," MEMACCESS(2) " \n"
"99: \n"
: "+a"(x0), // %0
"+d"(x1), // %1
: "=&a"(x0), // %0
"=&d"(x1), // %1
"+r"(dst_argb), // %2
"+r"(src_argb), // %3
"+r"(dst_width) // %4
@ -1179,7 +1179,7 @@ static uvec8 kShuffleFractions = {
// Bilinear row filtering combines 4x2 -> 4x1. SSSE3 version
void ScaleARGBFilterCols_SSSE3(uint8* dst_argb, const uint8* src_argb,
int dst_width, int x, int dx) {
intptr_t x0 = 0, x1 = 0;
intptr_t x0, x1;
asm volatile (
"movdqa %0,%%xmm4 \n"
"movdqa %1,%%xmm5 \n"
@ -1242,8 +1242,8 @@ void ScaleARGBFilterCols_SSSE3(uint8* dst_argb, const uint8* src_argb,
: "+r"(dst_argb), // %0
"+r"(src_argb), // %1
"+rm"(dst_width), // %2
"+r"(x0), // %3
"+r"(x1) // %4
"=&r"(x0), // %3
"=&r"(x1) // %4
: "rm"(x), // %5
"rm"(dx) // %6
: "memory", "cc", NACL_R14

View file

@ -21,8 +21,8 @@ extern "C" {
defined(__mips_dsp) && (__mips_dsp_rev >= 2) && \
(_MIPS_SIM == _MIPS_SIM_ABI32)
void ScaleRowDown2_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width) {
void ScaleRowDown2_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width) {
__asm__ __volatile__(
".set push \n"
".set noreorder \n"
@ -77,8 +77,8 @@ void ScaleRowDown2_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
);
}
void ScaleRowDown2Box_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width) {
void ScaleRowDown2Box_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width) {
const uint8* t = src_ptr + src_stride;
__asm__ __volatile__ (
@ -176,8 +176,8 @@ void ScaleRowDown2Box_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
);
}
void ScaleRowDown4_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width) {
void ScaleRowDown4_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width) {
__asm__ __volatile__ (
".set push \n"
".set noreorder \n"
@ -231,8 +231,8 @@ void ScaleRowDown4_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
);
}
void ScaleRowDown4Box_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width) {
void ScaleRowDown4Box_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width) {
intptr_t stride = src_stride;
const uint8* s1 = src_ptr + stride;
const uint8* s2 = s1 + stride;
@ -310,8 +310,8 @@ void ScaleRowDown4Box_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
);
}
void ScaleRowDown34_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width) {
void ScaleRowDown34_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width) {
__asm__ __volatile__ (
".set push \n"
".set noreorder \n"
@ -356,8 +356,8 @@ void ScaleRowDown34_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
);
}
void ScaleRowDown34_0_Box_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* d, int dst_width) {
void ScaleRowDown34_0_Box_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* d, int dst_width) {
__asm__ __volatile__ (
".set push \n"
".set noreorder \n"
@ -412,8 +412,8 @@ void ScaleRowDown34_0_Box_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
);
}
void ScaleRowDown34_1_Box_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* d, int dst_width) {
void ScaleRowDown34_1_Box_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* d, int dst_width) {
__asm__ __volatile__ (
".set push \n"
".set noreorder \n"
@ -464,8 +464,8 @@ void ScaleRowDown34_1_Box_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
);
}
void ScaleRowDown38_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width) {
void ScaleRowDown38_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width) {
__asm__ __volatile__ (
".set push \n"
".set noreorder \n"
@ -510,8 +510,8 @@ void ScaleRowDown38_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
);
}
void ScaleRowDown38_2_Box_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst_ptr, int dst_width) {
void ScaleRowDown38_2_Box_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst_ptr, int dst_width) {
intptr_t stride = src_stride;
const uint8* t = src_ptr + stride;
const int c = 0x2AAA;
@ -563,9 +563,9 @@ void ScaleRowDown38_2_Box_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
);
}
void ScaleRowDown38_3_Box_MIPS_DSPR2(const uint8* src_ptr,
ptrdiff_t src_stride,
uint8* dst_ptr, int dst_width) {
void ScaleRowDown38_3_Box_DSPR2(const uint8* src_ptr,
ptrdiff_t src_stride,
uint8* dst_ptr, int dst_width) {
intptr_t stride = src_stride;
const uint8* s1 = src_ptr + stride;
stride += stride;

View file

@ -532,7 +532,7 @@ void ScaleRowDown38_2_Box_NEON(const uint8* src_ptr,
void ScaleAddRows_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
uint16* dst_ptr, int src_width, int src_height) {
const uint8* src_tmp = NULL;
const uint8* src_tmp;
asm volatile (
"1: \n"
"mov %0, %1 \n"
@ -552,12 +552,12 @@ void ScaleAddRows_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
"add %1, %1, #16 \n"
"subs %4, %4, #16 \n" // 16 processed per loop
"bgt 1b \n"
: "+r"(src_tmp), // %0
"+r"(src_ptr), // %1
"+r"(dst_ptr), // %2
"+r"(src_stride), // %3
"+r"(src_width), // %4
"+r"(src_height) // %5
: "=&r"(src_tmp), // %0
"+r"(src_ptr), // %1
"+r"(dst_ptr), // %2
"+r"(src_stride), // %3
"+r"(src_width), // %4
"+r"(src_height) // %5
:
: "memory", "cc", "r12", "q0", "q1", "q2", "q3" // Clobber List
);
@ -909,7 +909,7 @@ void ScaleARGBRowDownEvenBox_NEON(const uint8* src_argb, ptrdiff_t src_stride,
void ScaleARGBCols_NEON(uint8* dst_argb, const uint8* src_argb,
int dst_width, int x, int dx) {
int tmp = 0;
int tmp;
const uint8* src_tmp = src_argb;
asm volatile (
"1: \n"
@ -926,13 +926,13 @@ void ScaleARGBCols_NEON(uint8* dst_argb, const uint8* src_argb,
"vst1.32 {q0, q1}, [%0]! \n" // store pixels
"subs %2, %2, #8 \n" // 8 processed per loop
"bgt 1b \n"
: "+r"(dst_argb), // %0
"+r"(src_argb), // %1
"+r"(dst_width), // %2
"+r"(x), // %3
"+r"(dx), // %4
"+r"(tmp), // %5
"+r"(src_tmp) // %6
: "+r"(dst_argb), // %0
"+r"(src_argb), // %1
"+r"(dst_width), // %2
"+r"(x), // %3
"+r"(dx), // %4
"=&r"(tmp), // %5
"+r"(src_tmp) // %6
:
: "memory", "cc", "q0", "q1"
);

View file

@ -547,7 +547,7 @@ void ScaleRowDown38_2_Box_NEON(const uint8* src_ptr,
void ScaleAddRows_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
uint16* dst_ptr, int src_width, int src_height) {
const uint8* src_tmp = NULL;
const uint8* src_tmp;
asm volatile (
"1: \n"
"mov %0, %1 \n"
@ -567,12 +567,12 @@ void ScaleAddRows_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
"add %1, %1, #16 \n"
"subs %w4, %w4, #16 \n" // 16 processed per loop
"b.gt 1b \n"
: "+r"(src_tmp), // %0
"+r"(src_ptr), // %1
"+r"(dst_ptr), // %2
"+r"(src_stride), // %3
"+r"(src_width), // %4
"+r"(src_height) // %5
: "=&r"(src_tmp), // %0
"+r"(src_ptr), // %1
"+r"(dst_ptr), // %2
"+r"(src_stride), // %3
"+r"(src_width), // %4
"+r"(src_height) // %5
:
: "memory", "cc", "w12", "v0", "v1", "v2", "v3" // Clobber List
);
@ -931,7 +931,7 @@ void ScaleARGBCols_NEON(uint8* dst_argb, const uint8* src_argb,
int64 dst_width64 = (int64) dst_width; // Work around ios 64 bit warning.
int64 x64 = (int64) x;
int64 dx64 = (int64) dx;
int64 tmp64 = 0;
int64 tmp64;
asm volatile (
"1: \n"
LOAD1_DATA32_LANE(v0, 0)
@ -947,13 +947,13 @@ void ScaleARGBCols_NEON(uint8* dst_argb, const uint8* src_argb,
"st1 {v0.4s, v1.4s}, [%0], #32 \n" // store pixels
"subs %w2, %w2, #8 \n" // 8 processed per loop
"b.gt 1b \n"
: "+r"(dst_argb), // %0
"+r"(src_argb), // %1
"+r"(dst_width64), // %2
"+r"(x64), // %3
"+r"(dx64), // %4
"+r"(tmp64), // %5
"+r"(src_tmp) // %6
: "+r"(dst_argb), // %0
"+r"(src_argb), // %1
"+r"(dst_width64), // %2
"+r"(x64), // %3
"+r"(dx64), // %4
"=&r"(tmp64), // %5
"+r"(src_tmp) // %6
:
: "memory", "cc", "v0", "v1"
);

View file

@ -289,7 +289,7 @@ void ScaleRowDown2Box_AVX2(const uint8* src_ptr, ptrdiff_t src_stride,
vpmaddubsw ymm3, ymm3, ymm4
vpaddw ymm0, ymm0, ymm2 // vertical add
vpaddw ymm1, ymm1, ymm3
vpsrlw ymm0, ymm0, 1
vpsrlw ymm0, ymm0, 1 // (x + 2) / 4 = (x / 2 + 1) / 2
vpsrlw ymm1, ymm1, 1
vpavgw ymm0, ymm0, ymm5 // (x + 1) / 2
vpavgw ymm1, ymm1, ymm5

View file

@ -1,11 +0,0 @@
#include "sqlite/sqlite3.h"
#include "sqlite.h"
void throw_sqlite3_exception(JNIEnv *env, sqlite3 *handle, int errcode) {
if (SQLITE_OK == errcode) {
errcode = sqlite3_errcode(handle);
}
const char *errmsg = sqlite3_errmsg(handle);
jclass exClass = (*env)->FindClass(env, "org/telegram/SQLite/SQLiteException");
(*env)->ThrowNew(env, exClass, errmsg);
}

View file

@ -1,10 +0,0 @@
#ifndef sqlite_h
#define sqlite_h
#include <jni.h>
#include "sqlite/sqlite3.h"
void throw_sqlite3_exception(JNIEnv* env, sqlite3 *handle, int errcode);
jint sqliteOnJNILoad(JavaVM *vm, void *reserved, JNIEnv *env);
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,79 +0,0 @@
#include "sqlite.h"
int Java_org_telegram_SQLite_SQLiteCursor_columnType(JNIEnv *env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
return sqlite3_column_type(handle, columnIndex);
}
int Java_org_telegram_SQLite_SQLiteCursor_columnIsNull(JNIEnv *env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
int valType = sqlite3_column_type(handle, columnIndex);
return SQLITE_NULL == valType;
}
int Java_org_telegram_SQLite_SQLiteCursor_columnIntValue(JNIEnv *env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
int valType = sqlite3_column_type(handle, columnIndex);
if (SQLITE_NULL == valType) {
return 0;
}
return sqlite3_column_int(handle, columnIndex);
}
long long Java_org_telegram_SQLite_SQLiteCursor_columnLongValue(JNIEnv *env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
int valType = sqlite3_column_type(handle, columnIndex);
if (SQLITE_NULL == valType) {
return 0;
}
return sqlite3_column_int64(handle, columnIndex);
}
double Java_org_telegram_SQLite_SQLiteCursor_columnDoubleValue(JNIEnv *env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
int valType = sqlite3_column_type(handle, columnIndex);
if (SQLITE_NULL == valType) {
return 0;
}
return sqlite3_column_double(handle, columnIndex);
}
jstring Java_org_telegram_SQLite_SQLiteCursor_columnStringValue(JNIEnv *env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
const char *str = sqlite3_column_text(handle, columnIndex);
if (str != 0) {
return (*env)->NewStringUTF(env, str);
}
return 0;
}
jbyteArray Java_org_telegram_SQLite_SQLiteCursor_columnByteArrayValue(JNIEnv *env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
void *buf = sqlite3_column_blob(handle, columnIndex);
int length = sqlite3_column_bytes(handle, columnIndex);
if (buf != 0 && length > 0) {
jbyteArray result = (*env)->NewByteArray(env, length);
(*env)->SetByteArrayRegion(env, result, 0, length, buf);
return result;
}
return 0;
}
int Java_org_telegram_SQLite_SQLiteCursor_columnByteArrayLength(JNIEnv *env, jobject object, int statementHandle, int columnIndex) {
return sqlite3_column_bytes((sqlite3_stmt *)statementHandle, columnIndex);
}
int Java_org_telegram_SQLite_SQLiteCursor_columnByteBufferValue(JNIEnv *env, jobject object, int statementHandle, int columnIndex, jobject buffer) {
if (!buffer) {
return 0;
}
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
void *buf = sqlite3_column_blob(handle, columnIndex);
int length = sqlite3_column_bytes(handle, columnIndex);
if (buf != 0 && length > 0) {
jbyte *byteBuff = (*env)->GetDirectBufferAddress(env, buffer);
memcpy(byteBuff, buf, length);
return length;
}
return 0;
}

View file

@ -1,42 +0,0 @@
#include "sqlite.h"
void Java_org_telegram_SQLite_SQLiteDatabase_closedb(JNIEnv *env, jobject object, int sqliteHandle) {
sqlite3 *handle = (sqlite3 *)sqliteHandle;
int err = sqlite3_close(handle);
if (SQLITE_OK != err) {
throw_sqlite3_exception(env, handle, err);
}
}
void Java_org_telegram_SQLite_SQLiteDatabase_beginTransaction(JNIEnv *env, jobject object, int sqliteHandle) {
sqlite3 *handle = (sqlite3 *)sqliteHandle;
sqlite3_exec(handle, "BEGIN", 0, 0, 0);
}
void Java_org_telegram_SQLite_SQLiteDatabase_commitTransaction(JNIEnv *env, jobject object, int sqliteHandle) {
sqlite3 *handle = (sqlite3 *)sqliteHandle;
sqlite3_exec(handle, "COMMIT", 0, 0, 0);
}
int Java_org_telegram_SQLite_SQLiteDatabase_opendb(JNIEnv *env, jobject object, jstring fileName, jstring tempDir) {
char const *fileNameStr = (*env)->GetStringUTFChars(env, fileName, 0);
char const *tempDirStr = (*env)->GetStringUTFChars(env, tempDir, 0);
if (sqlite3_temp_directory != 0) {
sqlite3_free(sqlite3_temp_directory);
}
sqlite3_temp_directory = sqlite3_mprintf("%s", tempDirStr);
sqlite3 *handle = 0;
int err = sqlite3_open(fileNameStr, &handle);
if (SQLITE_OK != err) {
throw_sqlite3_exception(env, handle, err);
}
if (fileNameStr != 0) {
(*env)->ReleaseStringUTFChars(env, fileName, fileNameStr);
}
if (tempDirStr != 0) {
(*env)->ReleaseStringUTFChars(env, tempDir, tempDirStr);
}
return (int)handle;
}

View file

@ -1,120 +0,0 @@
#include "sqlite.h"
jfieldID queryArgsCountField;
jint sqliteOnJNILoad(JavaVM *vm, void *reserved, JNIEnv *env) {
jclass class = (*env)->FindClass(env, "org/telegram/SQLite/SQLitePreparedStatement");
queryArgsCountField = (*env)->GetFieldID(env, class, "queryArgsCount", "I");
return JNI_VERSION_1_6;
}
int Java_org_telegram_SQLite_SQLitePreparedStatement_step(JNIEnv *env, jobject object, int statementHandle) {
sqlite3_stmt *handle = (sqlite3_stmt *) statementHandle;
int errcode = sqlite3_step(handle);
if (errcode == SQLITE_ROW) {
return 0;
} else if(errcode == SQLITE_DONE) {
return 1;
} else if(errcode == SQLITE_BUSY) {
return -1;
}
throw_sqlite3_exception(env, sqlite3_db_handle(handle), errcode);
}
int Java_org_telegram_SQLite_SQLitePreparedStatement_prepare(JNIEnv *env, jobject object, int sqliteHandle, jstring sql) {
sqlite3 *handle = (sqlite3 *) sqliteHandle;
char const *sqlStr = (*env)->GetStringUTFChars(env, sql, 0);
sqlite3_stmt *stmt_handle;
int errcode = sqlite3_prepare_v2(handle, sqlStr, -1, &stmt_handle, 0);
if (SQLITE_OK != errcode) {
throw_sqlite3_exception(env, handle, errcode);
} else {
int argsCount = sqlite3_bind_parameter_count(stmt_handle);
(*env)->SetIntField(env, object, queryArgsCountField, argsCount);
}
if (sqlStr != 0) {
(*env)->ReleaseStringUTFChars(env, sql, sqlStr);
}
return (int) stmt_handle;
}
void Java_org_telegram_SQLite_SQLitePreparedStatement_reset(JNIEnv *env, jobject object, int statementHandle) {
sqlite3_stmt *handle = (sqlite3_stmt *) statementHandle;
int errcode = sqlite3_reset(handle);
if (SQLITE_OK != errcode) {
throw_sqlite3_exception(env, sqlite3_db_handle(handle), errcode);
}
}
void Java_org_telegram_SQLite_SQLitePreparedStatement_finalize(JNIEnv *env, jobject object, int statementHandle) {
sqlite3_finalize((sqlite3_stmt *) statementHandle);
}
void Java_org_telegram_SQLite_SQLitePreparedStatement_bindByteBuffer(JNIEnv *env, jobject object, int statementHandle, int index, jobject value, int length) {
sqlite3_stmt *handle = (sqlite3_stmt *) statementHandle;
jbyte *buf = (*env)->GetDirectBufferAddress(env, value);
int errcode = sqlite3_bind_blob(handle, index, buf, length, SQLITE_STATIC);
if (SQLITE_OK != errcode) {
throw_sqlite3_exception(env, sqlite3_db_handle(handle), errcode);
}
}
void Java_org_telegram_SQLite_SQLitePreparedStatement_bindString(JNIEnv *env, jobject object, int statementHandle, int index, jstring value) {
sqlite3_stmt *handle = (sqlite3_stmt *) statementHandle;
char const *valueStr = (*env)->GetStringUTFChars(env, value, 0);
int errcode = sqlite3_bind_text(handle, index, valueStr, -1, SQLITE_TRANSIENT);
if (SQLITE_OK != errcode) {
throw_sqlite3_exception(env, sqlite3_db_handle(handle), errcode);
}
if (valueStr != 0) {
(*env)->ReleaseStringUTFChars(env, value, valueStr);
}
}
void Java_org_telegram_SQLite_SQLitePreparedStatement_bindInt(JNIEnv *env, jobject object, int statementHandle, int index, int value) {
sqlite3_stmt *handle = (sqlite3_stmt *) statementHandle;
int errcode = sqlite3_bind_int(handle, index, value);
if (SQLITE_OK != errcode) {
throw_sqlite3_exception(env, sqlite3_db_handle(handle), errcode);
}
}
void Java_org_telegram_SQLite_SQLitePreparedStatement_bindLong(JNIEnv *env, jobject object, int statementHandle, int index, long long value) {
sqlite3_stmt *handle = (sqlite3_stmt *) statementHandle;
int errcode = sqlite3_bind_int64(handle, index, value);
if (SQLITE_OK != errcode) {
throw_sqlite3_exception(env, sqlite3_db_handle(handle), errcode);
}
}
void Java_org_telegram_SQLite_SQLitePreparedStatement_bindDouble(JNIEnv *env, jobject object, int statementHandle, int index, double value) {
sqlite3_stmt *handle = (sqlite3_stmt *) statementHandle;
int errcode = sqlite3_bind_double(handle, index, value);
if (SQLITE_OK != errcode) {
throw_sqlite3_exception(env, sqlite3_db_handle(handle), errcode);
}
}
void Java_org_telegram_SQLite_SQLitePreparedStatement_bindNull(JNIEnv *env, jobject object, int statementHandle, int index) {
sqlite3_stmt *handle = (sqlite3_stmt *) statementHandle;
int errcode = sqlite3_bind_null(handle, index);
if (SQLITE_OK != errcode) {
throw_sqlite3_exception(env, sqlite3_db_handle(handle), errcode);
}
}

View file

@ -1378,7 +1378,7 @@ NativeByteBuffer *Datacenter::createRequestsData(std::vector<std::unique_ptr<Net
DEBUG_D("connection(%p, dc%u, type %d) send message (session: 0x%llx, seqno: %d, messageid: 0x%llx): %s(%p)", connection, datacenterId, connection->getConnectionType(), (uint64_t) connection->getSissionId(), networkMessage->message->seqno, (uint64_t) networkMessage->message->msg_id, typeid(*messageBody).name(), messageBody);
int64_t messageTime = (int64_t) (networkMessage->message->msg_id / 4294967296.0 * 1000);
int64_t currentTime = ConnectionsManager::getInstance().getCurrentTimeMillis() + (int64_t) timeDifference * 1000;
int64_t currentTime = ConnectionsManager::getInstance().getCurrentTimeMillis() + (int64_t) ConnectionsManager::getInstance().getTimeDifference() * 1000;
if (messageTime < currentTime - 30000 || messageTime > currentTime + 25000) {
DEBUG_D("wrap message in container");

View file

@ -947,6 +947,7 @@ void TL_config::readParams(NativeByteBuffer *stream, bool &error) {
push_chat_limit = stream->readInt32(&error);
saved_gifs_limit = stream->readInt32(&error);
edit_time_limit = stream->readInt32(&error);
rating_e_decay = stream->readInt32(&error);
magic = stream->readUint32(&error);
if (magic != 0x1cb5c415) {
error = true;
@ -989,6 +990,7 @@ void TL_config::serializeToStream(NativeByteBuffer *stream) {
stream->writeInt32(push_chat_limit);
stream->writeInt32(saved_gifs_limit);
stream->writeInt32(edit_time_limit);
stream->writeInt32(rating_e_decay);
stream->writeInt32(0x1cb5c415);
count = (uint32_t) disabled_features.size();
stream->writeInt32(count);

View file

@ -657,7 +657,7 @@ public:
class TL_config : public TLObject {
public:
static const uint32_t constructor = 0x317ceef4;
static const uint32_t constructor = 0xc9411388;
int32_t date;
int32_t expires;
@ -678,6 +678,7 @@ public:
int32_t push_chat_limit;
int32_t saved_gifs_limit;
int32_t edit_time_limit;
int32_t rating_e_decay;
std::vector<std::unique_ptr<TL_disabledFeature>> disabled_features;
static TL_config *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, bool &error);

View file

@ -15,6 +15,8 @@
<uses-feature android:name="android.hardware.wifi" android:required="false" />
<uses-feature android:name="android.hardware.screen.PORTRAIT" android:required="false" />
<uses-feature android:name="android.hardware.microphone" android:required="false" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera2" android:required="false" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
@ -37,6 +39,10 @@
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission android:name="android.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"/>
<!--<uses-permission android:name="android.permission.CAMERA" />-->
<application
android:name=".ApplicationLoader"
@ -121,6 +127,11 @@
android:name="org.telegram.ui.IntroActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
</activity>
<activity
android:name="org.telegram.messenger.OpenChatReceiver"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:exported="true">
</activity>
<activity
android:name="org.telegram.ui.PopupNotificationActivity"
android:configChanges="keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
@ -191,6 +202,11 @@
<service android:name=".ClearCacheService" android:exported="false"/>
<service android:name=".VideoEncodingService" android:enabled="true"/>
<service android:name=".MusicPlayerService" android:exported="true" android:enabled="true"/>
<service android:name=".MusicBrowserService" android:exported="true">
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
<receiver android:name=".MusicPlayerReceiver" >
<intent-filter>
@ -222,6 +238,7 @@
<meta-data android:name="com.sec.android.multiwindow.MINIMUM_SIZE_W" android:value="632dp" />
<meta-data android:name="com.sec.android.multiwindow.MINIMUM_SIZE_H" android:value="598dp" />
<meta-data android:name="com.google.android.gms.car.notification.SmallIcon" android:resource="@drawable/ic_player" />
<meta-data android:name="com.google.android.gms.car.application" android:resource="@xml/automotive_app_desc" />
</application>

View file

@ -182,41 +182,47 @@ public class PhoneFormat {
if (!initialzed) {
return orig;
}
String str = strip(orig);
try {
String str = strip(orig);
if (str.startsWith("+")) {
String rest = str.substring(1);
CallingCodeInfo info = findCallingCodeInfo(rest);
if (info != null) {
String phone = info.format(rest);
return "+" + phone;
} else {
return orig;
}
} else {
CallingCodeInfo info = callingCodeInfo(defaultCallingCode);
if (info == null) {
return orig;
}
String accessCode = info.matchingAccessCode(str);
if (accessCode != null) {
String rest = str.substring(accessCode.length());
String phone = rest;
CallingCodeInfo info2 = findCallingCodeInfo(rest);
if (info2 != null) {
phone = info2.format(rest);
}
if (phone.length() == 0) {
return accessCode;
if (str.startsWith("+")) {
String rest = str.substring(1);
CallingCodeInfo info = findCallingCodeInfo(rest);
if (info != null) {
String phone = info.format(rest);
return "+" + phone;
} else {
return String.format("%s %s", accessCode, phone);
return orig;
}
} else {
return info.format(str);
CallingCodeInfo info = callingCodeInfo(defaultCallingCode);
if (info == null) {
return orig;
}
String accessCode = info.matchingAccessCode(str);
if (accessCode != null) {
String rest = str.substring(accessCode.length());
String phone = rest;
CallingCodeInfo info2 = findCallingCodeInfo(rest);
if (info2 != null) {
phone = info2.format(rest);
}
if (phone.length() == 0) {
return accessCode;
} else {
return String.format("%s %s", accessCode, phone);
}
} else {
return info.format(str);
}
}
} catch (Exception e) {
FileLog.e("tmessages", e);
return orig;
}
}
public boolean isPhoneNumberValid(String phoneNumber) {

View file

@ -11,8 +11,6 @@ package org.telegram.SQLite;
import org.telegram.messenger.FileLog;
import org.telegram.tgnet.NativeByteBuffer;
import java.nio.ByteBuffer;
public class SQLiteCursor {
public static final int FIELD_TYPE_INT = 1;
@ -58,19 +56,13 @@ public class SQLiteCursor {
return columnByteArrayValue(preparedStatement.getStatementHandle(), columnIndex);
}
public int byteArrayLength(int columnIndex) throws SQLiteException {
checkRow();
return columnByteArrayLength(preparedStatement.getStatementHandle(), columnIndex);
}
public int byteBufferValue(int columnIndex, ByteBuffer buffer) throws SQLiteException {
checkRow();
return columnByteBufferValue(preparedStatement.getStatementHandle(), columnIndex, buffer);
}
public int byteBufferValue(int columnIndex, NativeByteBuffer buffer) throws SQLiteException {
public NativeByteBuffer byteBufferValue(int columnIndex) throws SQLiteException {
checkRow();
return columnByteBufferValue(preparedStatement.getStatementHandle(), columnIndex, buffer.buffer);
int ptr = columnByteBufferValue(preparedStatement.getStatementHandle(), columnIndex);
if (ptr != 0) {
return NativeByteBuffer.wrap(ptr);
}
return null;
}
public int getTypeOf(int columnIndex) throws SQLiteException {
@ -123,6 +115,5 @@ public class SQLiteCursor {
native double columnDoubleValue(int statementHandle, int columnIndex);
native String columnStringValue(int statementHandle, int columnIndex);
native byte[] columnByteArrayValue(int statementHandle, int columnIndex);
native int columnByteArrayLength(int statementHandle, int columnIndex);
native int columnByteBufferValue(int statementHandle, int columnIndex, ByteBuffer buffer);
native int columnByteBufferValue(int statementHandle, int columnIndex);
}

View file

@ -12,16 +12,14 @@ import org.telegram.messenger.FileLog;
import org.telegram.tgnet.NativeByteBuffer;
import java.nio.ByteBuffer;
import java.util.HashMap;
public class SQLitePreparedStatement {
private boolean isFinalized = false;
private int sqliteStatementHandle;
private int queryArgsCount;
private boolean finalizeAfterQuery = false;
private static HashMap<SQLitePreparedStatement, String> hashMap;
//private static HashMap<SQLitePreparedStatement, String> hashMap;
public int getStatementHandle() {
return sqliteStatementHandle;
@ -43,7 +41,7 @@ public class SQLitePreparedStatement {
public SQLiteCursor query(Object[] args) throws SQLiteException {
if (args == null || args.length != queryArgsCount) {
if (args == null) {
throw new IllegalArgumentException();
}

View file

@ -20,9 +20,15 @@ import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
@ -99,6 +105,9 @@ public class AndroidUtilities {
private static Boolean isTablet = null;
private static int adjustOwnerClassGuid = 0;
private static Paint roundPaint;
private static RectF bitmapRect;
public static Pattern WEB_URL = null;
static {
try {
@ -277,6 +286,21 @@ public class AndroidUtilities {
}
}
public static boolean isInternalUri(Uri uri) {
String pathString = uri.getPath();
if (pathString == null) {
return false;
}
while (true) {
String newPath = Utilities.readlink(pathString);
if (newPath == null || newPath.equals(pathString)) {
break;
}
pathString = newPath;
}
return pathString != null && pathString.toLowerCase().contains("/data/data/" + ApplicationLoader.applicationContext.getPackageName() + "/files");
}
public static void lockOrientation(Activity activity) {
if (activity == null || prevOrientation != -10) {
return;
@ -380,27 +404,40 @@ public class AndroidUtilities {
if (view == null) {
return;
}
InputMethodManager inputManager = (InputMethodManager)view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
try {
InputMethodManager inputManager = (InputMethodManager)view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
public static boolean isKeyboardShowed(View view) {
if (view == null) {
return false;
}
InputMethodManager inputManager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
return inputManager.isActive(view);
try {
InputMethodManager inputManager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
return inputManager.isActive(view);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
return false;
}
public static void hideKeyboard(View view) {
if (view == null) {
return;
}
InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (!imm.isActive()) {
return;
try {
InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (!imm.isActive()) {
return;
}
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
public static File getCacheDir() {
@ -673,6 +710,137 @@ public class AndroidUtilities {
}
}
private static Intent createShortcutIntent(long did, boolean forDelete) {
Intent shortcutIntent = new Intent(ApplicationLoader.applicationContext, OpenChatReceiver.class);
int lower_id = (int) did;
int high_id = (int) (did >> 32);
TLRPC.User user = null;
TLRPC.Chat chat = null;
if (lower_id == 0) {
shortcutIntent.putExtra("encId", high_id);
TLRPC.EncryptedChat encryptedChat = MessagesController.getInstance().getEncryptedChat(high_id);
if (encryptedChat == null) {
return null;
}
user = MessagesController.getInstance().getUser(encryptedChat.user_id);
} else if (lower_id > 0) {
shortcutIntent.putExtra("userId", lower_id);
user = MessagesController.getInstance().getUser(lower_id);
} else if (lower_id < 0) {
chat = MessagesController.getInstance().getChat(-lower_id);
shortcutIntent.putExtra("chatId", -lower_id);
} else {
return null;
}
if (user == null && chat == null) {
return null;
}
String name;
TLRPC.FileLocation photo = null;
if (user != null) {
name = ContactsController.formatName(user.first_name, user.last_name);
if (user.photo != null) {
photo = user.photo.photo_small;
}
} else {
name = chat.title;
if (chat.photo != null) {
photo = chat.photo.photo_small;
}
}
shortcutIntent.setAction("com.tmessages.openchat" + did);
shortcutIntent.addFlags(0x4000000);
Intent addIntent = new Intent();
addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);
addIntent.putExtra("duplicate", false);
if (!forDelete) {
Bitmap bitmap = null;
if (photo != null) {
try {
File path = FileLoader.getPathToAttach(photo, true);
bitmap = BitmapFactory.decodeFile(path.toString());
if (bitmap != null) {
int size = AndroidUtilities.dp(58);
Bitmap result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
result.eraseColor(Color.TRANSPARENT);
Canvas canvas = new Canvas(result);
BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
if (roundPaint == null) {
roundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
bitmapRect = new RectF();
}
float scale = size / (float) bitmap.getWidth();
canvas.save();
canvas.scale(scale, scale);
roundPaint.setShader(shader);
bitmapRect.set(0, 0, bitmap.getWidth(), bitmap.getHeight());
canvas.drawRoundRect(bitmapRect, bitmap.getWidth(), bitmap.getHeight(), roundPaint);
canvas.restore();
Drawable drawable = ApplicationLoader.applicationContext.getResources().getDrawable(R.drawable.book_logo);
int w = AndroidUtilities.dp(15);
int left = size - w - AndroidUtilities.dp(2);
int top = size - w - AndroidUtilities.dp(2);
drawable.setBounds(left, top, left + w, top + w);
drawable.draw(canvas);
try {
canvas.setBitmap(null);
} catch (Exception e) {
//don't promt, this will crash on 2.x
}
bitmap = result;
}
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
}
if (bitmap != null) {
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, bitmap);
} else {
if (user != null) {
if (user.bot) {
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(ApplicationLoader.applicationContext, R.drawable.book_bot));
} else {
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(ApplicationLoader.applicationContext, R.drawable.book_user));
}
} else if (chat != null) {
if (ChatObject.isChannel(chat) && !chat.megagroup) {
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(ApplicationLoader.applicationContext, R.drawable.book_channel));
} else {
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(ApplicationLoader.applicationContext, R.drawable.book_group));
}
}
}
}
return addIntent;
}
public static void installShortcut(long did) {
try {
Intent addIntent = createShortcutIntent(did, false);
addIntent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
ApplicationLoader.applicationContext.sendBroadcast(addIntent);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
public static void uninstallShortcut(long did) {
try {
Intent addIntent = createShortcutIntent(did, true);
addIntent.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");
ApplicationLoader.applicationContext.sendBroadcast(addIntent);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
public static int getViewInset(View view) {
if (view == null || Build.VERSION.SDK_INT < 21 || view.getHeight() == AndroidUtilities.displaySize.y || view.getHeight() == AndroidUtilities.displaySize.y - statusBarHeight) {
return 0;
@ -924,6 +1092,21 @@ public class AndroidUtilities {
}
}
public static void addToClipboard(CharSequence str) {
try {
if (Build.VERSION.SDK_INT < 11) {
android.text.ClipboardManager clipboard = (android.text.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE);
clipboard.setText(str);
} else {
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE);
android.content.ClipData clip = android.content.ClipData.newPlainText("label", str);
clipboard.setPrimaryClip(clip);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
public static void addMediaToGallery(String fromPath) {
if (fromPath == null) {
return;

View file

@ -20,9 +20,6 @@ import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
@ -373,8 +370,14 @@ public class ApplicationLoader extends Application {
}
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
return resultCode == ConnectionResult.SUCCESS;
try {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
return resultCode == ConnectionResult.SUCCESS;
} catch (Exception e) {
FileLog.e("tmessages", e);
}
return true;
/*if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, this, PLAY_SERVICES_RESOLUTION_REQUEST).show();

View file

@ -10,8 +10,8 @@ package org.telegram.messenger;
public class BuildVars {
public static boolean DEBUG_VERSION = false;
public static int BUILD_VERSION = 787;
public static String BUILD_VERSION_STRING = "3.8";
public static int BUILD_VERSION = 803;
public static String BUILD_VERSION_STRING = "3.9";
public static int APP_ID = 0; //obtain your own APP_ID at https://core.telegram.org/api/obtaining_api_id
public static String APP_HASH = ""; //obtain your own APP_HASH at https://core.telegram.org/api/obtaining_api_id
public static String HOCKEY_APP_HASH = "your-hockeyapp-api-key-here";

View file

@ -43,6 +43,7 @@ public class FileLoadOperation {
private volatile int state = stateIdle;
private int downloadedBytes;
private int totalBytesCount;
private int bytesCountPadding;
private FileLoadOperationDelegate delegate;
private byte[] key;
private byte[] iv;
@ -110,8 +111,13 @@ public class FileLoadOperation {
location.access_hash = documentLocation.access_hash;
datacenter_id = documentLocation.dc_id;
}
if (totalBytesCount <= 0) {
totalBytesCount = documentLocation.size;
totalBytesCount = documentLocation.size;
if (key != null) {
int toAdd = 0;
if (totalBytesCount % 16 != 0) {
bytesCountPadding = 16 - totalBytesCount % 16;
totalBytesCount += bytesCountPadding;
}
}
ext = FileLoader.getDocumentFileName(documentLocation);
int idx;
@ -405,8 +411,15 @@ public class FileLoadOperation {
onFinishLoadingFile();
return;
}
int currentBytesSize = requestInfo.response.bytes.limit();
downloadedBytes += currentBytesSize;
boolean finishedDownloading = currentBytesSize != currentDownloadChunkSize || (totalBytesCount == downloadedBytes || downloadedBytes % currentDownloadChunkSize != 0) && (totalBytesCount <= 0 || totalBytesCount <= downloadedBytes);
if (key != null) {
Utilities.aesIgeEncryption(requestInfo.response.bytes.buffer, key, iv, false, true, 0, requestInfo.response.bytes.limit());
if (finishedDownloading && bytesCountPadding != 0) {
requestInfo.response.bytes.limit(requestInfo.response.bytes.limit() - bytesCountPadding);
}
}
if (fileOutputStream != null) {
FileChannel channel = fileOutputStream.getChannel();
@ -416,10 +429,8 @@ public class FileLoadOperation {
fiv.seek(0);
fiv.write(iv);
}
int currentBytesSize = requestInfo.response.bytes.limit();
downloadedBytes += currentBytesSize;
if (totalBytesCount > 0 && state == stateDownloading) {
delegate.didChangedLoadProgress(FileLoadOperation.this, Math.min(1.0f, (float)downloadedBytes / (float)totalBytesCount));
delegate.didChangedLoadProgress(FileLoadOperation.this, Math.min(1.0f, (float) downloadedBytes / (float) totalBytesCount));
}
for (int a = 0; a < delayedRequestInfos.size(); a++) {
@ -433,14 +444,10 @@ public class FileLoadOperation {
}
}
if (currentBytesSize != currentDownloadChunkSize) {
if (finishedDownloading) {
onFinishLoadingFile();
} else {
if (totalBytesCount != downloadedBytes && downloadedBytes % currentDownloadChunkSize == 0 || totalBytesCount > 0 && totalBytesCount > downloadedBytes) {
startDownloadRequest();
} else {
onFinishLoadingFile();
}
startDownloadRequest();
}
} catch (Exception e) {
cleanup();

View file

@ -481,16 +481,12 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
}
if (bitmapDrawable instanceof AnimatedFileDrawable) {
drawRegion.set(imageX, imageY, imageX + imageW, imageY + imageH);
if (bitmapW / scaleH > imageW) {
bitmapW /= scaleH;
drawRegion.set(imageX - (bitmapW - imageW) / 2, imageY, imageX + (bitmapW + imageW) / 2, imageY + imageH);
} else {
if (bitmapW / scaleH > imageW) {
bitmapW /= scaleH;
drawRegion.set(imageX - (bitmapW - imageW) / 2, imageY, imageX + (bitmapW + imageW) / 2, imageY + imageH);
} else {
bitmapH /= scaleW;
drawRegion.set(imageX, imageY - (bitmapH - imageH) / 2, imageX + imageW, imageY + (bitmapH + imageH) / 2);
}
bitmapH /= scaleW;
drawRegion.set(imageX, imageY - (bitmapH - imageH) / 2, imageX + imageW, imageY + (bitmapH + imageH) / 2);
}
if (orientation % 360 == 90 || orientation % 360 == 270) {
int width = (drawRegion.right - drawRegion.left) / 2;

View file

@ -374,7 +374,7 @@ public class LocaleController {
if (languageNameInEnglish.contains("&") || languageNameInEnglish.contains("|")) {
return false;
}
if (languageCode.contains("&") || languageCode.contains("|")) {
if (languageCode.contains("&") || languageCode.contains("|") || languageCode.contains("/") || languageCode.contains("\\")) {
return false;
}

View file

@ -239,6 +239,14 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
private int hasAudioFocus;
private boolean callInProgress;
private int audioFocus = AUDIO_NO_FOCUS_NO_DUCK;
private boolean resumeAudioOnFocusGain;
private static final float VOLUME_DUCK = 0.2f;
private static final float VOLUME_NORMAL = 1.0f;
private static final int AUDIO_NO_FOCUS_NO_DUCK = 0;
private static final int AUDIO_NO_FOCUS_CAN_DUCK = 1;
private static final int AUDIO_FOCUSED = 2;
private ArrayList<MessageObject> videoConvertQueue = new ArrayList<>();
private final Object videoQueueSync = new Object();
@ -303,6 +311,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
private ArrayList<MessageObject> playlist = new ArrayList<>();
private ArrayList<MessageObject> shuffledPlaylist = new ArrayList<>();
private int currentPlaylistNum;
private boolean forceLoopCurrentPlaylist;
private boolean downloadingCurrentMessage;
private boolean playMusicAgain;
private AudioInfo audioInfo;
@ -369,7 +378,9 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
sampleStep = (float) len / 2 / (float) newPart;
for (int i = 0; i < len / 2; i++) {
short peak = buffer.getShort();
sum += peak * peak;
if (peak > 2500) {
sum += peak * peak;
}
if (i == (int) nextNum && currentNum < recordSamples.length) {
recordSamples[currentNum] = peak;
nextNum += sampleStep;
@ -668,8 +679,8 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
@Override
public void onCallStateChanged(int state, String incomingNumber) {
if (state == TelephonyManager.CALL_STATE_RINGING) {
if (MediaController.getInstance().isPlayingAudio(MediaController.getInstance().getPlayingMessageObject()) && !MediaController.getInstance().isAudioPaused()) {
MediaController.getInstance().pauseAudio(MediaController.getInstance().getPlayingMessageObject());
if (isPlayingAudio(getPlayingMessageObject()) && !isAudioPaused()) {
pauseAudio(getPlayingMessageObject());
} else if (recordStartRunnable != null || recordingAudio != null) {
stopRecording(2);
}
@ -693,12 +704,46 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
@Override
public void onAudioFocusChange(int focusChange) {
if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
if (MediaController.getInstance().isPlayingAudio(MediaController.getInstance().getPlayingMessageObject()) && !MediaController.getInstance().isAudioPaused()) {
MediaController.getInstance().pauseAudio(MediaController.getInstance().getPlayingMessageObject());
if (isPlayingAudio(getPlayingMessageObject()) && !isAudioPaused()) {
pauseAudio(getPlayingMessageObject());
}
hasAudioFocus = 0;
audioFocus = AUDIO_NO_FOCUS_NO_DUCK;
} else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
//MediaController.getInstance().playAudio(MediaController.getInstance().getPlayingMessageObject());
audioFocus = AUDIO_FOCUSED;
if (resumeAudioOnFocusGain) {
resumeAudioOnFocusGain = false;
if (isPlayingAudio(getPlayingMessageObject()) && isAudioPaused()) {
playAudio(getPlayingMessageObject());
}
}
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
audioFocus = AUDIO_NO_FOCUS_CAN_DUCK;
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
audioFocus = AUDIO_NO_FOCUS_NO_DUCK;
if (isPlayingAudio(getPlayingMessageObject()) && !isAudioPaused()) {
pauseAudio(getPlayingMessageObject());
resumeAudioOnFocusGain = true;
}
}
setPlayerVolume();
}
private void setPlayerVolume() {
try {
float volume;
if (audioFocus != AUDIO_NO_FOCUS_CAN_DUCK) {
volume = VOLUME_NORMAL;
} else {
volume = VOLUME_DUCK;
}
if (audioPlayer != null) {
audioPlayer.setVolume(volume, volume);
} else if (audioTrackPlayer != null) {
audioTrackPlayer.setStereoVolume(volume, volume);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
@ -1936,6 +1981,10 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
return playingMessageObject;
}
public int getPlayingMessageObjectNum() {
return currentPlaylistNum;
}
private void buildShuffledPlayList() {
if (playlist.isEmpty()) {
return;
@ -1956,9 +2005,14 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
public boolean setPlaylist(ArrayList<MessageObject> messageObjects, MessageObject current) {
return setPlaylist(messageObjects, current, true);
}
public boolean setPlaylist(ArrayList<MessageObject> messageObjects, MessageObject current, boolean loadMusic) {
if (playingMessageObject == current) {
return playAudio(current);
}
forceLoopCurrentPlaylist = !loadMusic;
playMusicAgain = !playlist.isEmpty();
playlist.clear();
for (int a = messageObjects.size() - 1; a >= 0; a--) {
@ -1978,7 +2032,9 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
buildShuffledPlayList();
currentPlaylistNum = 0;
}
SharedMediaQuery.loadMusic(current.getDialogId(), playlist.get(0).getId());
if (loadMusic) {
SharedMediaQuery.loadMusic(current.getDialogId(), playlist.get(0).getId());
}
}
return playAudio(current);
}
@ -1987,10 +2043,19 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
playNextMessage(false);
}
public void playMessageAtIndex(int index) {
if (currentPlaylistNum < 0 || currentPlaylistNum >= playlist.size()) {
return;
}
currentPlaylistNum = index;
playMusicAgain = true;
playAudio(playlist.get(currentPlaylistNum));
}
private void playNextMessage(boolean byStop) {
ArrayList<MessageObject> currentPlayList = shuffleMusic ? shuffledPlaylist : playlist;
if (byStop && repeatMode == 2) {
if (byStop && repeatMode == 2 && !forceLoopCurrentPlaylist) {
cleanupPlayer(false, false);
playAudio(currentPlayList.get(currentPlaylistNum));
return;
@ -1998,7 +2063,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
currentPlaylistNum++;
if (currentPlaylistNum >= currentPlayList.size()) {
currentPlaylistNum = 0;
if (byStop && repeatMode == 0) {
if (byStop && repeatMode == 0 && !forceLoopCurrentPlaylist) {
if (audioPlayer != null || audioTrackPlayer != null) {
if (audioPlayer != null) {
try {
@ -2118,10 +2183,14 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
if (hasAudioFocus != neededAudioFocus) {
hasAudioFocus = neededAudioFocus;
int result;
if (neededAudioFocus == 3) {
NotificationsController.getInstance().audioManager.requestAudioFocus(this, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN);
result = NotificationsController.getInstance().audioManager.requestAudioFocus(this, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN);
} else {
NotificationsController.getInstance().audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, neededAudioFocus == 2 ? AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK : AudioManager.AUDIOFOCUS_GAIN);
result = NotificationsController.getInstance().audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, neededAudioFocus == 2 ? AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK : AudioManager.AUDIOFOCUS_GAIN);
}
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
audioFocus = AUDIO_FOCUSED;
}
}
}
@ -2270,6 +2339,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
}
checkAudioFocus(messageObject);
setPlayerVolume();
isPaused = false;
lastProgress = 0;
@ -2880,8 +2950,9 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
public static String getFileName(Uri uri) {
String result = null;
if (uri.getScheme().equals("content")) {
Cursor cursor = ApplicationLoader.applicationContext.getContentResolver().query(uri, null, null, null, null);
Cursor cursor = null;
try {
cursor = ApplicationLoader.applicationContext.getContentResolver().query(uri, new String[]{OpenableColumns.DISPLAY_NAME}, null, null, null);
if (cursor.moveToFirst()) {
result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}

View file

@ -29,6 +29,7 @@ import org.telegram.ui.Components.URLSpanBotCommand;
import org.telegram.ui.Components.URLSpanNoUnderline;
import org.telegram.ui.Components.URLSpanNoUnderlineBold;
import org.telegram.ui.Components.URLSpanReplacement;
import org.telegram.ui.Components.URLSpanUserMention;
import java.io.File;
import java.util.AbstractMap;
@ -461,6 +462,7 @@ public class MessageObject {
}
public void setType() {
int oldType = type;
if (messageOwner instanceof TLRPC.TL_message || messageOwner instanceof TLRPC.TL_messageForwarded_old2) {
if (isMediaEmpty()) {
type = 0;
@ -513,6 +515,9 @@ public class MessageObject {
type = 10;
}
}
if (oldType != 1000 && oldType != type) {
generateThumbs(false);
}
}
public void checkLayout() {
@ -879,7 +884,20 @@ public class MessageObject {
generateLinkDescription();
textLayoutBlocks = new ArrayList<>();
boolean useManualParse = messageOwner.entities.isEmpty() && (
boolean hasEntities;
if (messageOwner.send_state != MESSAGE_SEND_STATE_SENT) {
hasEntities = false;
for (int a = 0; a < messageOwner.entities.size(); a++) {
if (!(messageOwner.entities.get(a) instanceof TLRPC.TL_inputMessageEntityMentionName)) {
hasEntities = true;
break;
}
}
} else {
hasEntities = !messageOwner.entities.isEmpty();
}
boolean useManualParse = !hasEntities && (
messageOwner instanceof TLRPC.TL_message_old ||
messageOwner instanceof TLRPC.TL_message_old2 ||
messageOwner instanceof TLRPC.TL_message_old3 ||
@ -932,6 +950,10 @@ public class MessageObject {
spannable.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/ritalic.ttf")), entity.offset, entity.offset + entity.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (entity instanceof TLRPC.TL_messageEntityCode || entity instanceof TLRPC.TL_messageEntityPre) {
spannable.setSpan(new TypefaceSpan(Typeface.MONOSPACE, AndroidUtilities.dp(MessagesController.getInstance().fontSize - 1)), entity.offset, entity.offset + entity.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (entity instanceof TLRPC.TL_messageEntityMentionName) {
spannable.setSpan(new URLSpanUserMention("" + ((TLRPC.TL_messageEntityMentionName) entity).user_id), entity.offset, entity.offset + entity.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (entity instanceof TLRPC.TL_inputMessageEntityMentionName) {
spannable.setSpan(new URLSpanUserMention("" + ((TLRPC.TL_inputMessageEntityMentionName) entity).user_id.user_id), entity.offset, entity.offset + entity.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (!useManualParse) {
String url = messageOwner.message.substring(entity.offset, entity.offset + entity.length);
if (entity instanceof TLRPC.TL_messageEntityBotCommand) {
@ -967,7 +989,7 @@ public class MessageObject {
maxWidth = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) - AndroidUtilities.dp(80);
}
}
if (fromUser != null && fromUser.bot) {
if (fromUser != null && fromUser.bot || (isMegagroup() || messageOwner.fwd_from != null && messageOwner.fwd_from.channel_id != 0) && !isOut()) {
maxWidth -= AndroidUtilities.dp(20);
}
@ -1467,6 +1489,16 @@ public class MessageObject {
}
}
public String getStickerEmoji() {
for (int a = 0; a < messageOwner.media.document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = messageOwner.media.document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeSticker) {
return attribute.alt != null && attribute.alt.length() > 0 ? attribute.alt : null;
}
}
return null;
}
public boolean isSticker() {
if (type != 1000) {
return type == 13;
@ -1524,6 +1556,22 @@ public class MessageObject {
return "";
}
public int getDuration() {
TLRPC.Document document;
if (type == 0) {
document = messageOwner.media.webpage.document;
} else {
document = messageOwner.media.document;
}
for (int a = 0; a < document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeAudio) {
return attribute.duration;
}
}
return 0;
}
public String getMusicAuthor() {
TLRPC.Document document;
if (type == 0) {
@ -1599,7 +1647,7 @@ public class MessageObject {
}
if (message.to_id.channel_id == 0) {
return message.out && (message.media instanceof TLRPC.TL_messageMediaPhoto ||
message.media instanceof TLRPC.TL_messageMediaDocument && (isVideoMessage(message) || isGifDocument(message.media.document)) ||
message.media instanceof TLRPC.TL_messageMediaDocument && !isStickerMessage(message) ||
message.media instanceof TLRPC.TL_messageMediaEmpty ||
message.media instanceof TLRPC.TL_messageMediaWebPage ||
message.media == null);
@ -1612,7 +1660,7 @@ public class MessageObject {
}
if (chat.megagroup && message.out || !chat.megagroup && (chat.creator || chat.editor && isOut(message)) && isImportant(message)) {
if (message.media instanceof TLRPC.TL_messageMediaPhoto ||
message.media instanceof TLRPC.TL_messageMediaDocument && (isVideoMessage(message) || isGifDocument(message.media.document)) ||
message.media instanceof TLRPC.TL_messageMediaDocument && !isStickerMessage(message) ||
message.media instanceof TLRPC.TL_messageMediaEmpty ||
message.media instanceof TLRPC.TL_messageMediaWebPage ||
message.media == null) {

View file

@ -25,6 +25,7 @@ import android.widget.Toast;
import org.telegram.SQLite.SQLiteCursor;
import org.telegram.messenger.query.BotQuery;
import org.telegram.messenger.query.MessagesQuery;
import org.telegram.messenger.query.SearchQuery;
import org.telegram.messenger.query.StickersQuery;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.RequestDelegate;
@ -138,6 +139,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
public int minGroupConvertSize = 200;
public int maxEditTime = 172800;
public int groupBigSize;
public int ratingDecay;
private ArrayList<TLRPC.TL_disabledFeature> disabledFeatures = new ArrayList<>();
private class UserActionUpdatesSeq extends TLRPC.Updates {
@ -204,6 +206,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
maxMegagroupCount = preferences.getInt("maxMegagroupCount", 1000);
maxEditTime = preferences.getInt("maxEditTime", 3600);
groupBigSize = preferences.getInt("groupBigSize", 10);
ratingDecay = preferences.getInt("ratingDecay", 2419200);
fontSize = preferences.getInt("fons_size", AndroidUtilities.isTablet() ? 18 : 16);
String disabledFeaturesString = preferences.getString("disabledFeatures", null);
if (disabledFeaturesString != null && disabledFeaturesString.length() != 0) {
@ -235,6 +238,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
groupBigSize = config.chat_big_size;
disabledFeatures = config.disabled_features;
maxEditTime = config.edit_time_limit;
ratingDecay = config.rating_e_decay;
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
@ -243,6 +247,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
editor.putInt("maxMegagroupCount", maxMegagroupCount);
editor.putInt("groupBigSize", groupBigSize);
editor.putInt("maxEditTime", maxEditTime);
editor.putInt("ratingDecay", ratingDecay);
try {
SerializedData data = new SerializedData();
data.writeInt32(disabledFeatures.size());
@ -468,6 +473,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
SendMessagesHelper.getInstance().cleanUp();
SecretChatHelper.getInstance().cleanUp();
StickersQuery.cleanup();
SearchQuery.cleanUp();
reloadingWebpages.clear();
reloadingWebpagesPending.clear();
@ -1341,6 +1347,11 @@ public class MessagesController implements NotificationCenter.NotificationCenter
return;
}
blockedUsers.add(user_id);
if (user.bot) {
SearchQuery.removeInline(user_id);
} else {
SearchQuery.removePeer(user_id);
}
NotificationCenter.getInstance().postNotificationName(NotificationCenter.blockedUsersDidLoaded);
TLRPC.TL_contacts_block req = new TLRPC.TL_contacts_block();
req.id = getInputUser(user);
@ -1626,6 +1637,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter
MessagesStorage.getInstance().deleteDialog(did, onlyHistory);
return;
}
if (onlyHistory == 0) {
AndroidUtilities.uninstallShortcut(did);
}
if (first) {
TLRPC.Dialog dialog = dialogs_dict.get(did);
@ -2235,7 +2249,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
int reqId = ConnectionsManager.getInstance().sendRequest(request, new RequestDelegate() {
@Override
public void run(TLObject response, TLRPC.TL_error error) {
if (error == null) {
if (response != null) {
final TLRPC.messages_Messages res = (TLRPC.messages_Messages) response;
if (res.messages.size() > count) {
res.messages.remove(0);
@ -4147,7 +4161,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
public void generateUpdateMessage() {
if (UserConfig.lastUpdateVersion == null || UserConfig.lastUpdateVersion.equals(BuildVars.BUILD_VERSION_STRING)) {
if (BuildVars.DEBUG_VERSION || UserConfig.lastUpdateVersion == null || UserConfig.lastUpdateVersion.equals(BuildVars.BUILD_VERSION_STRING)) {
return;
}
TLRPC.TL_help_getAppChangelog req = new TLRPC.TL_help_getAppChangelog();
@ -4628,7 +4642,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
long dialog_id = -channelId;
Integer value = dialogs_read_inbox_max.get(dialog_id);
if (value == null) {
value = MessagesStorage.getInstance().getChannelReadInboxMax(channelId);
value = MessagesStorage.getInstance().getDialogReadInboxMax(dialog_id);
}
MessageObject obj = new MessageObject(message, usersDict, createdDialogIds.contains(dialog_id));
@ -4683,6 +4697,13 @@ public class MessagesController implements NotificationCenter.NotificationCenter
processChannelsUpdatesQueue(channelId, 1);
MessagesStorage.getInstance().saveChannelPts(channelId, res.pts);
} else if (res instanceof TLRPC.TL_updates_channelDifferenceTooLong) {
long dialog_id = -channelId;
Integer value = dialogs_read_inbox_max.get(dialog_id);
if (value == null) {
value = MessagesStorage.getInstance().getDialogReadInboxMax(dialog_id);
}
value = Math.max(value, res.read_inbox_max_id);
dialogs_read_inbox_max.put(dialog_id, value);
for (int a = 0; a < res.messages.size(); a++) {
TLRPC.Message message = res.messages.get(a);
message.dialog_id = -channelId;
@ -4696,11 +4717,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
message.unread = false;
message.media_unread = false;
}
if (channelFinal != null && channelFinal.megagroup) {
message.flags |= TLRPC.MESSAGE_FLAG_MEGAGROUP;
}
if (channelFinal != null && channelFinal.left || res.read_inbox_max_id >= message.id) {
if (channelFinal != null && channelFinal.left || value >= message.id) {
message.unread = false;
message.media_unread = false;
}
@ -4724,7 +4741,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
getChannelDifference(channelId);
}
FileLog.e("tmessages", "received channel difference with pts = " + res.pts + " channelId = " + channelId);
FileLog.e("tmessages", "messages = " + res.new_messages.size() + " users = " + res.users.size() + " chats = " + res.chats.size() + " other updates = " + res.other_updates.size());
FileLog.e("tmessages", "new_messages = " + res.new_messages.size() + " messages = " + res.messages.size() + " users = " + res.users.size() + " chats = " + res.chats.size() + " other updates = " + res.other_updates.size());
}
});
}
@ -5151,7 +5168,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
TLRPC.User user3 = null;
TLRPC.Chat channel = null;
if (user == null || user.min) { //TODO
if (user == null || user.min) {
user = MessagesStorage.getInstance().getUserSync(user_id);
if (user != null && user.min) {
user = null;
@ -5200,6 +5217,26 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
missingData = chat == null || user == null || needFwdUser && user2 == null && channel == null || needBotUser && user3 == null;
}
if (!missingData && !updates.entities.isEmpty()) {
for (int a = 0; a < updates.entities.size(); a++) {
TLRPC.MessageEntity entity = updates.entities.get(a);
if (entity instanceof TLRPC.TL_messageEntityMentionName) {
int uid = ((TLRPC.TL_messageEntityMentionName) entity).user_id;
TLRPC.User entityUser = getUser(uid);
if (entityUser == null || entityUser.min) {
entityUser = MessagesStorage.getInstance().getUserSync(uid);
if (entityUser != null && entityUser.min) {
entityUser = null;
}
if (entityUser == null) {
missingData = true;
break;
}
putUser(user, true);
}
}
}
}
if (user != null && user.status != null && user.status.expires <= 0) {
onlinePrivacy.put(user.id, ConnectionsManager.getInstance().getCurrentTime());
updateStatus = true;
@ -5697,9 +5734,17 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
}
for (int a = 0; a < 3; a++) {
int count = 3 + message.entities.size();
for (int a = 0; a < count; a++) {
if (a != 0) {
user_id = a == 1 ? message.from_id : (message.fwd_from != null ? message.fwd_from.from_id : 0);
if (a == 1) {
user_id = message.from_id;
} else if (a == 2) {
user_id = message.fwd_from != null ? message.fwd_from.from_id : 0;
} else {
TLRPC.MessageEntity entity = message.entities.get(a - 3);
user_id = entity instanceof TLRPC.TL_messageEntityMentionName ? ((TLRPC.TL_messageEntityMentionName) entity).user_id : 0;
}
}
if (user_id > 0) {
TLRPC.User user = usersDict.get(user_id);
@ -5745,7 +5790,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
long dialog_id = -update.channel_id;
Integer value = dialogs_read_inbox_max.get(dialog_id);
if (value == null) {
value = MessagesStorage.getInstance().getChannelReadInboxMax(update.channel_id);
value = MessagesStorage.getInstance().getDialogReadInboxMax(dialog_id);
}
if (value >= message.id || ChatObject.isNotInChat(chat)) {
message.unread = false;
@ -6094,7 +6139,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
long dialog_id = -update.channel_id;
Integer value = dialogs_read_inbox_max.get(dialog_id);
if (value == null) {
value = MessagesStorage.getInstance().getChannelReadInboxMax(update.channel_id);
value = MessagesStorage.getInstance().getDialogReadInboxMax(dialog_id);
}
dialogs_read_inbox_max.put(dialog_id, Math.max(value, update.max_id));
} else if (update instanceof TLRPC.TL_updateDeleteChannelMessages) {
@ -6130,30 +6175,46 @@ public class MessagesController implements NotificationCenter.NotificationCenter
TLRPC.Message message;
if (update instanceof TLRPC.TL_updateEditChannelMessage) {
message = ((TLRPC.TL_updateEditChannelMessage) update).message;
TLRPC.Chat chat = chatsDict.get(message.to_id.channel_id);
if (chat == null) {
chat = getChat(message.to_id.channel_id);
}
if (chat == null) {
chat = MessagesStorage.getInstance().getChatSync(message.to_id.channel_id);
putChat(chat, true);
}
if (chat != null && chat.megagroup) {
message.flags |= TLRPC.MESSAGE_FLAG_MEGAGROUP;
}
} else {
message = ((TLRPC.TL_updateEditMessage) update).message;
}
if (message.to_id.channel_id != 0 && !message.out) {
message.unread = true;
if (message.post || (message.flags & TLRPC.MESSAGE_FLAG_MEGAGROUP) != 0) {
message.media_unread = true;
if (message.out && (message.message == null || message.message.length() == 0)) {
message.message = "-1";
message.attachPath = "";
}
int count = message.entities.size();
for (int a = 0; a < count; a++) {
TLRPC.MessageEntity entity = message.entities.get(a);
if (entity instanceof TLRPC.TL_messageEntityMentionName) {
int user_id = ((TLRPC.TL_messageEntityMentionName) entity).user_id;
TLRPC.User user = usersDict.get(user_id);
if (user == null || user.min) {
user = getUser(user_id);
}
if (user == null || user.min) {
user = MessagesStorage.getInstance().getUserSync(user_id);
if (user != null && user.min) {
user = null;
}
putUser(user, true);
}
if (user == null) {
return false;
}
}
}
if (update instanceof TLRPC.TL_updateEditChannelMessage) {
long dialog_id = -update.channel_id;
Integer value = dialogs_read_inbox_max.get(dialog_id);
if (value == null) {
value = MessagesStorage.getInstance().getChannelReadInboxMax(update.channel_id);
}
if (value >= message.id) {
message.unread = false;
message.media_unread = false;
} //TODO unread for updateEditMessage?
}
ImageLoader.saveMessageThumbs(message);
if (message.to_id.chat_id != 0) {
message.dialog_id = -message.to_id.chat_id;
} else if (message.to_id.channel_id != 0) {
@ -6164,6 +6225,27 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
message.dialog_id = message.to_id.user_id;
}
if (!message.out) {
if (message.to_id.channel_id != 0) {
message.unread = true;
if (message.post || (message.flags & TLRPC.MESSAGE_FLAG_MEGAGROUP) != 0) {
message.media_unread = true;
}
}
Integer value = dialogs_read_inbox_max.get(message.dialog_id);
if (value == null) {
value = MessagesStorage.getInstance().getDialogReadInboxMax(message.dialog_id);
}
if (value >= message.id) {
message.unread = message.media_unread = false;
} else {
message.unread = message.media_unread = true;
}
}
ImageLoader.saveMessageThumbs(message);
MessageObject obj = new MessageObject(message, usersDict, chatsDict, createdDialogIds.contains(message.dialog_id));
ArrayList<MessageObject> arr = editingMessages.get(message.dialog_id);
@ -6417,6 +6499,14 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
boolean updateDialogs = false;
if (!messages.isEmpty()) {
for (HashMap.Entry<Long, ArrayList<MessageObject>> entry : messages.entrySet()) {
Long key = entry.getKey();
ArrayList<MessageObject> value = entry.getValue();
updateInterfaceWithMessages(key, value);
}
updateDialogs = true;
}
if (!editingMessages.isEmpty()) {
for (HashMap.Entry<Long, ArrayList<MessageObject>> pair : editingMessages.entrySet()) {
Long dialog_id = pair.getKey();
@ -6427,6 +6517,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter
MessageObject newMessage = arrayList.get(a);
if (oldObject.getId() == newMessage.getId()) {
dialogMessage.put(dialog_id, newMessage);
if (newMessage.messageOwner.to_id != null && newMessage.messageOwner.to_id.channel_id == 0) {
dialogMessagesByIds.put(newMessage.getId(), newMessage);
}
updateDialogs = true;
break;
}
@ -6435,14 +6528,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
NotificationCenter.getInstance().postNotificationName(NotificationCenter.replaceMessagesObjects, dialog_id, arrayList);
}
}
if (!messages.isEmpty()) {
for (HashMap.Entry<Long, ArrayList<MessageObject>> entry : messages.entrySet()) {
Long key = entry.getKey();
ArrayList<MessageObject> value = entry.getValue();
updateInterfaceWithMessages(key, value);
}
updateDialogs = true;
}
if (updateDialogs) {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
}
@ -6667,6 +6752,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
boolean isEncryptedChat = ((int) uid) == 0;
MessageObject lastMessage = null;
int channelId = 0;
boolean updateRating = false;
for (int a = 0; a < messages.size(); a++) {
MessageObject message = messages.get(a);
if (lastMessage == null || (!isEncryptedChat && message.getId() > lastMessage.getId() || (isEncryptedChat || message.getId() < 0 && lastMessage.getId() < 0) && message.getId() < lastMessage.getId()) || message.messageOwner.date > lastMessage.messageOwner.date) {
@ -6680,6 +6766,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter
if (message.isOut() && message.isNewGif() && !message.isSending() && !message.isForwarded()) {
addNewGifToRecent(message.messageOwner.media.document, message.messageOwner.date);
}
if (message.isOut() && message.isSent()) {
updateRating = true;
}
}
MessagesQuery.loadReplyMessagesForMessages(messages, uid);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.didReceivedNewMessages, uid, messages);
@ -6794,6 +6883,10 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
}
}
if (updateRating) {
SearchQuery.increasePeerRaiting(uid);
}
}
private static String getRestrictionReason(String reason) {

View file

@ -148,6 +148,9 @@ public class MessagesStorage {
database.executeFast("CREATE TABLE chat_pinned(uid INTEGER PRIMARY KEY, pinned INTEGER, data BLOB)").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS chat_pinned_mid_idx ON chat_pinned(uid, pinned) WHERE pinned != 0;").stepThis().dispose();
database.executeFast("CREATE TABLE chat_hints(did INTEGER, type INTEGER, rating REAL, date INTEGER, PRIMARY KEY(did, type))").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS chat_hints_rating_idx ON chat_hints(rating);").stepThis().dispose();
database.executeFast("CREATE TABLE users_data(uid INTEGER PRIMARY KEY, about TEXT)").stepThis().dispose();
database.executeFast("CREATE TABLE users(uid INTEGER PRIMARY KEY, name TEXT, status INTEGER, data BLOB)").stepThis().dispose();
database.executeFast("CREATE TABLE chats(uid INTEGER PRIMARY KEY, name TEXT, data BLOB)").stepThis().dispose();
@ -160,7 +163,6 @@ public class MessagesStorage {
database.executeFast("CREATE TABLE blocked_users(uid INTEGER PRIMARY KEY)").stepThis().dispose();
database.executeFast("CREATE TABLE dialog_settings(did INTEGER PRIMARY KEY, flags INTEGER);").stepThis().dispose();
database.executeFast("CREATE TABLE web_recent_v3(id TEXT, type INTEGER, image_url TEXT, thumb_url TEXT, local_url TEXT, width INTEGER, height INTEGER, size INTEGER, date INTEGER, document BLOB, PRIMARY KEY (id, type));").stepThis().dispose();
database.executeFast("CREATE TABLE bot_recent(id INTEGER PRIMARY KEY, date INTEGER);").stepThis().dispose();
database.executeFast("CREATE TABLE stickers_v2(id INTEGER PRIMARY KEY, data BLOB, date INTEGER, hash TEXT);").stepThis().dispose();
database.executeFast("CREATE TABLE hashtag_recent_v2(id TEXT PRIMARY KEY, date INTEGER);").stepThis().dispose();
database.executeFast("CREATE TABLE webpage_pending(id INTEGER, mid INTEGER, PRIMARY KEY (id, mid));").stepThis().dispose();
@ -172,7 +174,7 @@ public class MessagesStorage {
database.executeFast("CREATE TABLE bot_info(uid INTEGER PRIMARY KEY, info BLOB)").stepThis().dispose();
//version
database.executeFast("PRAGMA user_version = 31").stepThis().dispose();
database.executeFast("PRAGMA user_version = 32").stepThis().dispose();
//database.executeFast("CREATE TABLE secret_holes(uid INTEGER, seq_in INTEGER, seq_out INTEGER, data BLOB, PRIMARY KEY (uid, seq_in, seq_out));").stepThis().dispose();
//database.executeFast("CREATE TABLE attach_data(uid INTEGER, id INTEGER, data BLOB, PRIMARY KEY (uid, id))").stepThis().dispose();
@ -206,7 +208,7 @@ public class MessagesStorage {
}
}
int version = database.executeInt("PRAGMA user_version");
if (version < 31) {
if (version < 32) {
updateDbToLastVersion(version);
}
}
@ -301,17 +303,17 @@ public class MessagesStorage {
SQLitePreparedStatement state = database.executeFast("REPLACE INTO enc_tasks_v2 VALUES(?, ?)");
if (cursor.next()) {
int date = cursor.intValue(0);
int length;
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(1));
if ((length = cursor.byteBufferValue(1, data)) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(1);
if (data != null) {
int length = data.limit();
for (int a = 0; a < length / 4; a++) {
state.requery();
state.bindInteger(1, data.readInt32(false));
state.bindInteger(2, date);
state.step();
}
data.reuse();
}
data.reuse();
}
state.dispose();
cursor.dispose();
@ -422,9 +424,10 @@ public class MessagesStorage {
SQLitePreparedStatement state = database.executeFast("REPLACE INTO chat_settings_v2 VALUES(?, ?)");
while (cursor.next()) {
int chat_id = cursor.intValue(0);
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(1));
if (cursor.byteBufferValue(1, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(1);
if (data != null) {
TLRPC.ChatParticipants participants = TLRPC.ChatParticipants.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (participants != null) {
TLRPC.TL_chatFull chatFull = new TLRPC.TL_chatFull();
chatFull.id = chat_id;
@ -441,7 +444,6 @@ public class MessagesStorage {
data2.reuse();
}
}
data.reuse();
}
state.dispose();
cursor.dispose();
@ -486,7 +488,6 @@ public class MessagesStorage {
version = 28;
}
if (version == 28) {
database.executeFast("CREATE TABLE IF NOT EXISTS bot_recent(id INTEGER PRIMARY KEY, date INTEGER);").stepThis().dispose();
database.executeFast("PRAGMA user_version = 29").stepThis().dispose();
version = 29;
}
@ -503,7 +504,14 @@ public class MessagesStorage {
database.executeFast("CREATE INDEX IF NOT EXISTS chat_pinned_mid_idx ON chat_pinned(uid, pinned) WHERE pinned != 0;").stepThis().dispose();
database.executeFast("CREATE TABLE IF NOT EXISTS users_data(uid INTEGER PRIMARY KEY, about TEXT)").stepThis().dispose();
database.executeFast("PRAGMA user_version = 31").stepThis().dispose();
//version = 31;
version = 31;
}
if (version == 31) {
database.executeFast("DROP TABLE IF EXISTS bot_recent;").stepThis().dispose();
database.executeFast("CREATE TABLE IF NOT EXISTS chat_hints(did INTEGER, type INTEGER, rating REAL, date INTEGER, PRIMARY KEY(did, type))").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS chat_hints_rating_idx ON chat_hints(rating);").stepThis().dispose();
database.executeFast("PRAGMA user_version = 32").stepThis().dispose();
//version = 32;
}
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -662,9 +670,10 @@ public class MessagesStorage {
cursor = database.queryFinalized("SELECT read_state, data, send_state, mid, date, uid FROM messages WHERE uid IN (" + ids.toString() + ") AND out = 0 AND read_state IN(0,2) ORDER BY date DESC LIMIT 50");
while (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(1));
if (cursor.byteBufferValue(1, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(1);
if (data != null) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
MessageObject.setUnreadFlags(message, cursor.intValue(0));
message.id = cursor.intValue(3);
message.date = cursor.intValue(4);
@ -698,7 +707,6 @@ public class MessagesStorage {
message.random_id = cursor.longValue(5);
}
}
data.reuse();
}
cursor.dispose();
@ -792,11 +800,11 @@ public class MessagesStorage {
searchImage.size = cursor.intValue(6);
searchImage.date = cursor.intValue(7);
if (!cursor.isNull(8)) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(8));
if (cursor.byteBufferValue(8, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(8);
if (data != null) {
searchImage.document = TLRPC.Document.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
}
data.reuse();
}
searchImage.type = type;
arrayList.add(searchImage);
@ -936,12 +944,12 @@ public class MessagesStorage {
SQLiteCursor cursor = database.queryFinalized("SELECT data FROM wallpapers WHERE 1");
final ArrayList<TLRPC.WallPaper> wallPapers = new ArrayList<>();
while (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
TLRPC.WallPaper wallPaper = TLRPC.WallPaper.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
wallPapers.add(wallPaper);
}
data.reuse();
}
cursor.dispose();
AndroidUtilities.runOnUIThread(new Runnable() {
@ -1039,9 +1047,10 @@ public class MessagesStorage {
ArrayList<File> filesToDelete = new ArrayList<>();
try {
while (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (message != null && message.from_id == uid && message.id != 1) {
mids.add(message.id);
if (message.media instanceof TLRPC.TL_messageMediaPhoto) {
@ -1063,7 +1072,6 @@ public class MessagesStorage {
}
}
}
data.reuse();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -1103,9 +1111,10 @@ public class MessagesStorage {
ArrayList<File> filesToDelete = new ArrayList<>();
try {
while (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (message != null && message.media != null) {
if (message.media instanceof TLRPC.TL_messageMediaPhoto) {
for (TLRPC.PhotoSize photoSize : message.media.photo.sizes) {
@ -1126,7 +1135,6 @@ public class MessagesStorage {
}
}
}
data.reuse();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -1162,14 +1170,14 @@ public class MessagesStorage {
SQLiteCursor cursor2 = database.queryFinalized("SELECT data FROM messages WHERE uid = " + did + " AND mid IN (" + last_mid_i + "," + last_mid + ")");
try {
while (cursor2.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor2.byteArrayLength(0));
if (cursor2.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor2.byteBufferValue(0);
if (data != null) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (message != null) {
arrayList.add(message);
}
}
data.reuse();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -1239,12 +1247,12 @@ public class MessagesStorage {
final TLRPC.photos_Photos res = new TLRPC.photos_Photos();
while (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
TLRPC.Photo photo = TLRPC.Photo.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
res.photos.add(photo);
}
data.reuse();
}
cursor.dispose();
@ -1505,6 +1513,9 @@ public class MessagesStorage {
}
public void updateChatParticipants(final TLRPC.ChatParticipants participants) {
if (participants == null) {
return;
}
storageQueue.postRunnable(new Runnable() {
@Override
public void run() {
@ -1513,12 +1524,12 @@ public class MessagesStorage {
TLRPC.ChatFull info = null;
ArrayList<TLRPC.User> loadedUsers = new ArrayList<>();
if (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
info = TLRPC.ChatFull.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
info.pinned_msg_id = cursor.intValue(1);
}
data.reuse();
}
cursor.dispose();
if (info instanceof TLRPC.TL_chatFull) {
@ -1588,13 +1599,10 @@ public class MessagesStorage {
public void run() {
try {
if (ifExist) {
boolean dontExist = true;
SQLiteCursor cursor = database.queryFinalized("SELECT uid FROM chat_settings_v2 WHERE uid = " + info.id);
if (cursor.next()) {
dontExist = false;
}
boolean exist = cursor.next();
cursor.dispose();
if (dontExist) {
if (!exist) {
return;
}
}
@ -1609,27 +1617,34 @@ public class MessagesStorage {
data.reuse();
if (info instanceof TLRPC.TL_channelFull) {
SQLiteCursor cursor = database.queryFinalized("SELECT date, last_mid_i, pts, date_i, last_mid FROM dialogs WHERE did = " + (-info.id));
SQLiteCursor cursor = database.queryFinalized("SELECT date, last_mid_i, pts, date_i, last_mid, inbox_max FROM dialogs WHERE did = " + (-info.id));
if (cursor.next()) {
int dialog_date = cursor.intValue(0);
long last_mid_i = cursor.longValue(1);
int pts = cursor.intValue(2);
int dialog_date_i = cursor.intValue(3);
long last_mid = cursor.longValue(4);
int inbox_max = cursor.intValue(5);
if (inbox_max < info.read_inbox_max_id) {
int inbox_diff = info.read_inbox_max_id - inbox_max;
if (inbox_diff < info.unread_important_count) {
info.unread_important_count = inbox_diff;
}
int dialog_date = cursor.intValue(0);
long last_mid_i = cursor.longValue(1);
int pts = cursor.intValue(2);
int dialog_date_i = cursor.intValue(3);
long last_mid = cursor.longValue(4);
state = database.executeFast("REPLACE INTO dialogs VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
state.bindLong(1, -info.id);
state.bindInteger(2, dialog_date);
state.bindInteger(3, info.unread_important_count);
state.bindLong(4, last_mid);
state.bindInteger(5, info.read_inbox_max_id);
state.bindInteger(6, 0);
state.bindLong(7, last_mid_i);
state.bindInteger(8, info.unread_count);
state.bindInteger(9, pts);
state.bindInteger(10, dialog_date_i);
state.step();
state.dispose();
state = database.executeFast("REPLACE INTO dialogs VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
state.bindLong(1, -info.id);
state.bindInteger(2, dialog_date);
state.bindInteger(3, info.unread_important_count);
state.bindLong(4, last_mid);
state.bindInteger(5, info.read_inbox_max_id);
state.bindInteger(6, 0);
state.bindLong(7, last_mid_i);
state.bindInteger(8, info.unread_count);
state.bindInteger(9, pts);
state.bindInteger(10, dialog_date_i);
state.step();
state.dispose();
}
}
cursor.dispose();
}
@ -1649,12 +1664,12 @@ public class MessagesStorage {
TLRPC.ChatFull info = null;
ArrayList<TLRPC.User> loadedUsers = new ArrayList<>();
if (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
info = TLRPC.ChatFull.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
info.pinned_msg_id = cursor.intValue(1);
}
data.reuse();
}
cursor.dispose();
if (info instanceof TLRPC.TL_channelFull) {
@ -1695,12 +1710,12 @@ public class MessagesStorage {
TLRPC.ChatFull info = null;
ArrayList<TLRPC.User> loadedUsers = new ArrayList<>();
if (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
info = TLRPC.ChatFull.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
info.pinned_msg_id = cursor.intValue(1);
}
data.reuse();
}
cursor.dispose();
if (info instanceof TLRPC.TL_chatFull) {
@ -1782,11 +1797,11 @@ public class MessagesStorage {
TLRPC.ChatFull info = null;
ArrayList<TLRPC.User> loadedUsers = new ArrayList<>();
if (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
info = TLRPC.ChatFull.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
}
data.reuse();
}
cursor.dispose();
result[0] = info instanceof TLRPC.TL_channelFull && info.migrated_from_chat_id != 0;
@ -1820,12 +1835,12 @@ public class MessagesStorage {
try {
SQLiteCursor cursor = database.queryFinalized("SELECT info, pinned FROM chat_settings_v2 WHERE uid = " + chat_id);
if (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
info = TLRPC.ChatFull.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
info.pinned_msg_id = cursor.intValue(1);
}
data.reuse();
}
cursor.dispose();
@ -1846,27 +1861,31 @@ public class MessagesStorage {
info.participants = new TLRPC.TL_chatParticipants();
while (cursor.next()) {
try {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
NativeByteBuffer data2 = new NativeByteBuffer(cursor.byteArrayLength(2));
if (cursor.byteBufferValue(0, data) != 0 && cursor.byteBufferValue(2, data2) != 0) {
TLRPC.User user = TLRPC.User.TLdeserialize(data, data.readInt32(false), false);
TLRPC.ChannelParticipant participant = TLRPC.ChannelParticipant.TLdeserialize(data2, data2.readInt32(false), false);
if (user != null && participant != null) {
if (user.status != null) {
user.status.expires = cursor.intValue(1);
}
loadedUsers.add(user);
participant.date = cursor.intValue(3);
TLRPC.TL_chatChannelParticipant chatChannelParticipant = new TLRPC.TL_chatChannelParticipant();
chatChannelParticipant.user_id = participant.user_id;
chatChannelParticipant.date = participant.date;
chatChannelParticipant.inviter_id = participant.inviter_id;
chatChannelParticipant.channelParticipant = participant;
info.participants.participants.add(chatChannelParticipant);
}
TLRPC.User user = null;
TLRPC.ChannelParticipant participant = null;
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
user = TLRPC.User.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
}
data = cursor.byteBufferValue(2);
if (data != null) {
participant = TLRPC.ChannelParticipant.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
}
if (user != null && participant != null) {
if (user.status != null) {
user.status.expires = cursor.intValue(1);
}
loadedUsers.add(user);
participant.date = cursor.intValue(3);
TLRPC.TL_chatChannelParticipant chatChannelParticipant = new TLRPC.TL_chatChannelParticipant();
chatChannelParticipant.user_id = participant.user_id;
chatChannelParticipant.date = participant.date;
chatChannelParticipant.inviter_id = participant.inviter_id;
chatChannelParticipant.channelParticipant = participant;
info.participants.participants.add(chatChannelParticipant);
}
data.reuse();
data2.reuse();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
@ -2160,9 +2179,10 @@ public class MessagesStorage {
ArrayList<Integer> encryptedChatIds = new ArrayList<>();
SQLiteCursor cursor = database.queryFinalized("SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.uid, s.seq_in, s.seq_out, m.ttl FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid LEFT JOIN messages_seq as s ON m.mid = s.mid WHERE m.mid < 0 AND m.send_state = 1 ORDER BY m.mid DESC LIMIT " + count);
while (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(1));
if (cursor.byteBufferValue(1, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(1);
if (data != null) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (!messageHashMap.containsKey(message.id)) {
MessageObject.setUnreadFlags(message, cursor.intValue(0));
message.id = cursor.intValue(3);
@ -2213,7 +2233,6 @@ public class MessagesStorage {
}
}
}
data.reuse();
}
cursor.dispose();
@ -2357,6 +2376,24 @@ public class MessagesStorage {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT min(mid) FROM messages WHERE uid = %d AND out = 0 AND read_state IN(0,2) AND mid > 0" + imp, dialog_id));
if (cursor.next()) {
messageMaxId = max_id_query = min_unread_id = cursor.intValue(0);
if (messageMaxId != 0 && channelId != 0) {
messageMaxId |= ((long) channelId) << 32;
}
}
cursor.dispose();
}
} else {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT start, end FROM " + holesTable + " WHERE uid = %d AND start < %d AND end > %d", dialog_id, max_id_query, max_id_query));
boolean containMessage = !cursor.next();
cursor.dispose();
if (containMessage) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT min(mid) FROM messages WHERE uid = %d AND out = 0 AND read_state IN(0,2) AND mid > %d" + imp, dialog_id, max_id_query));
if (cursor.next()) {
messageMaxId = max_id_query = cursor.intValue(0);
if (messageMaxId != 0 && channelId != 0) {
messageMaxId |= ((long) channelId) << 32;
}
}
cursor.dispose();
}
@ -2560,9 +2597,10 @@ public class MessagesStorage {
}
if (cursor != null) {
while (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(1));
if (cursor.byteBufferValue(1, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(1);
if (data != null) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
MessageObject.setUnreadFlags(message, cursor.intValue(0));
message.id = cursor.intValue(3);
message.date = cursor.intValue(4);
@ -2570,21 +2608,23 @@ public class MessagesStorage {
if ((message.flags & TLRPC.MESSAGE_FLAG_HAS_VIEWS) != 0) {
message.views = cursor.intValue(7);
}
message.ttl = cursor.intValue(8);
if (lower_id != 0) {
message.ttl = cursor.intValue(8);
}
res.messages.add(message);
addUsersAndChatsFromMessage(message, usersToLoad, chatsToLoad);
if (message.reply_to_msg_id != 0 || message.reply_to_random_id != 0) {
if (!cursor.isNull(6)) {
NativeByteBuffer data2 = new NativeByteBuffer(cursor.byteArrayLength(6));
if (cursor.byteBufferValue(6, data2) != 0) {
message.replyMessage = TLRPC.Message.TLdeserialize(data2, data2.readInt32(false), false);
data = cursor.byteBufferValue(6);
if (data != null) {
message.replyMessage = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (message.replyMessage != null) {
addUsersAndChatsFromMessage(message.replyMessage, usersToLoad, chatsToLoad);
}
}
data2.reuse();
}
if (message.replyMessage == null) {
if (message.reply_to_msg_id != 0) {
@ -2633,7 +2673,6 @@ public class MessagesStorage {
}
}
}
data.reuse();
}
cursor.dispose();
}
@ -2701,9 +2740,10 @@ public class MessagesStorage {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid, m.date, r.random_id FROM randoms as r INNER JOIN messages as m ON r.mid = m.mid WHERE r.random_id IN(%s)", TextUtils.join(",", replyMessages)));
}
while (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
message.id = cursor.intValue(1);
message.date = cursor.intValue(2);
message.dialog_id = dialog_id;
@ -2728,7 +2768,6 @@ public class MessagesStorage {
}
}
}
data.reuse();
}
cursor.dispose();
if (!replyMessageRandomOwners.isEmpty()) {
@ -2816,16 +2855,16 @@ public class MessagesStorage {
if (id != null) {
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM sent_files_v2 WHERE uid = '%s' AND type = %d", id, type));
if (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
TLObject file = TLRPC.MessageMedia.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (file instanceof TLRPC.TL_messageMediaDocument) {
result.add(((TLRPC.TL_messageMediaDocument) file).document);
} else if (file instanceof TLRPC.TL_messageMediaPhoto) {
result.add(((TLRPC.TL_messageMediaDocument) file).photo);
}
}
data.reuse();
}
cursor.dispose();
}
@ -3186,9 +3225,10 @@ public class MessagesStorage {
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM users WHERE uid = %d", user.id));
if (cursor.next()) {
try {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
TLRPC.User oldUser = TLRPC.User.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (oldUser != null) {
if (user.username != null) {
oldUser.username = user.username;
@ -3207,11 +3247,11 @@ public class MessagesStorage {
user = oldUser;
}
}
data.reuse();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
cursor.dispose();
}
state.requery();
NativeByteBuffer data = new NativeByteBuffer(user.getObjectSize());
@ -3248,9 +3288,10 @@ public class MessagesStorage {
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM chats WHERE uid = %d", chat.id));
if (cursor.next()) {
try {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
TLRPC.Chat oldChat = TLRPC.Chat.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (oldChat != null) {
oldChat.title = chat.title;
oldChat.photo = chat.photo;
@ -3268,7 +3309,6 @@ public class MessagesStorage {
chat = oldChat;
}
}
data.reuse();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
@ -3298,9 +3338,10 @@ public class MessagesStorage {
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, status FROM users WHERE uid IN(%s)", usersToLoad));
while (cursor.next()) {
try {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
TLRPC.User user = TLRPC.User.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (user != null) {
if (user.status != null) {
user.status.expires = cursor.intValue(1);
@ -3308,7 +3349,6 @@ public class MessagesStorage {
result.add(user);
}
}
data.reuse();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
@ -3323,14 +3363,14 @@ public class MessagesStorage {
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM chats WHERE uid IN(%s)", chatsToLoad));
while (cursor.next()) {
try {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
TLRPC.Chat chat = TLRPC.Chat.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (chat != null) {
result.add(chat);
}
}
data.reuse();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
@ -3345,9 +3385,10 @@ public class MessagesStorage {
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, user, g, authkey, ttl, layer, seq_in, seq_out, use_count, exchange_id, key_date, fprint, fauthkey, khash FROM enc_chats WHERE uid IN(%s)", chatsToLoad));
while (cursor.next()) {
try {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
TLRPC.EncryptedChat chat = TLRPC.EncryptedChat.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (chat != null) {
chat.user_id = cursor.intValue(1);
if (usersToLoad != null && !usersToLoad.contains(chat.user_id)) {
@ -3370,7 +3411,6 @@ public class MessagesStorage {
result.add(chat);
}
}
data.reuse();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
@ -3462,16 +3502,16 @@ public class MessagesStorage {
DownloadObject downloadObject = new DownloadObject();
downloadObject.type = cursor.intValue(1);
downloadObject.id = cursor.longValue(0);
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(2));
if (cursor.byteBufferValue(2, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(2);
if (data != null) {
TLRPC.MessageMedia messageMedia = TLRPC.MessageMedia.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (messageMedia.document != null) {
downloadObject.object = messageMedia.document;
} else if (messageMedia.photo != null) {
downloadObject.object = FileLoader.getClosestPhotoSizeWithSize(messageMedia.photo.sizes, AndroidUtilities.getPhotoSize());
}
}
data.reuse();
objects.add(downloadObject);
}
cursor.dispose();
@ -3524,16 +3564,16 @@ public class MessagesStorage {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT mid, data FROM messages WHERE mid IN (%s)", TextUtils.join(",", mids)));
while (cursor.next()) {
int mid = cursor.intValue(0);
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(1));
if (cursor.byteBufferValue(1, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(1);
if (data != null) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
message.id = mid;
message.media.webpage = webPages.get(message.media.webpage.id);
messages.add(message);
}
}
data.reuse();
}
cursor.dispose();
@ -3547,7 +3587,8 @@ public class MessagesStorage {
SQLitePreparedStatement state = database.executeFast("UPDATE messages SET data = ? WHERE mid = ?");
SQLitePreparedStatement state2 = database.executeFast("UPDATE media_v2 SET data = ? WHERE mid = ?");
for (TLRPC.Message message : messages) {
for (int a = 0; a < messages.size(); a++) {
TLRPC.Message message = messages.get(a);
NativeByteBuffer data = new NativeByteBuffer(message.getObjectSize());
message.serializeToStream(data);
@ -4562,10 +4603,11 @@ public class MessagesStorage {
if ((int) did != 0) {
continue;
}
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(1));
if (cursor.byteBufferValue(1, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(1);
if (data != null) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
if (message != null && message.media != null) {
data.reuse();
if (message != null) {
if (message.media instanceof TLRPC.TL_messageMediaPhoto) {
for (TLRPC.PhotoSize photoSize : message.media.photo.sizes) {
File file = FileLoader.getPathToAttach(photoSize);
@ -4585,7 +4627,6 @@ public class MessagesStorage {
}
}
}
data.reuse();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -4677,9 +4718,10 @@ public class MessagesStorage {
dialogs.dialogs.add(dialog);
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(4));
if (cursor.byteBufferValue(4, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(4);
if (data != null) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
MessageObject.setUnreadFlags(message, cursor.intValue(5));
message.id = cursor.intValue(6);
message.send_state = cursor.intValue(7);
@ -4692,7 +4734,6 @@ public class MessagesStorage {
addUsersAndChatsFromMessage(message, usersToLoad, chatsToLoad);
}
data.reuse();
int lower_id = (int)dialog.id;
int high_id = (int)(dialog.id >> 32);
@ -5067,6 +5108,7 @@ public class MessagesStorage {
SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?)");
SQLitePreparedStatement state2 = database.executeFast("REPLACE INTO media_v2 VALUES(?, ?, ?, ?, ?)");
SQLitePreparedStatement state5 = null;
TLRPC.Message botKeyboard = null;
int countBeforeImportant = 0;
int countAfterImportant = 0;
@ -5086,8 +5128,18 @@ public class MessagesStorage {
}
if (load_type == -2) {
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT mid FROM messages WHERE mid = %d", messageId));
boolean exist = cursor.next();
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT mid, data FROM messages WHERE mid = %d", messageId));
boolean exist;
if (exist = cursor.next()) {
NativeByteBuffer data = cursor.byteBufferValue(1);
if (data != null) {
TLRPC.Message oldMessage = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (oldMessage != null) {
message.attachPath = oldMessage.attachPath;
}
}
}
cursor.dispose();
if (!exist) {
continue;
@ -5163,6 +5215,15 @@ public class MessagesStorage {
state2.step();
}
data.reuse();
if (message.media instanceof TLRPC.TL_messageMediaWebPage && message.media.webpage instanceof TLRPC.TL_webPagePending) {
if (state5 == null) {
state5 = database.executeFast("REPLACE INTO webpage_pending VALUES(?, ?)");
}
state5.requery();
state5.bindLong(1, message.media.webpage.id);
state5.bindLong(2, messageId);
state5.step();
}
if (load_type == 0 && isValidKeyboardToSave(message)) {
if (botKeyboard == null || botKeyboard.id < message.id) {
@ -5172,6 +5233,9 @@ public class MessagesStorage {
}
state.dispose();
state2.dispose();
if (state5 != null) {
state5.dispose();
}
if (botKeyboard != null) {
BotQuery.putBotKeyboard(dialog_id, botKeyboard);
}
@ -5277,6 +5341,16 @@ public class MessagesStorage {
}
}
}
if (!message.entities.isEmpty()) {
for (int a = 0; a < message.entities.size(); a++) {
TLRPC.MessageEntity entity = message.entities.get(a);
if (entity instanceof TLRPC.TL_messageEntityMentionName) {
usersToLoad.add(((TLRPC.TL_messageEntityMentionName) entity).user_id);
} else if (entity instanceof TLRPC.TL_inputMessageEntityMentionName) {
usersToLoad.add(((TLRPC.TL_inputMessageEntityMentionName) entity).user_id.user_id);
}
}
}
if (message.media != null) {
if (message.media.user_id != 0 && !usersToLoad.contains(message.media.user_id)) {
usersToLoad.add(message.media.user_id);
@ -5344,9 +5418,10 @@ public class MessagesStorage {
}
dialogs.dialogs.add(dialog);
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(4));
if (cursor.byteBufferValue(4, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(4);
if (data != null) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (message != null) {
MessageObject.setUnreadFlags(message, cursor.intValue(5));
message.id = cursor.intValue(6);
@ -5363,14 +5438,14 @@ public class MessagesStorage {
try {
if (message.reply_to_msg_id != 0 && message.action instanceof TLRPC.TL_messageActionPinMessage) {
if (!cursor.isNull(15)) {
NativeByteBuffer data2 = new NativeByteBuffer(cursor.byteArrayLength(15));
if (cursor.byteBufferValue(15, data2) != 0) {
message.replyMessage = TLRPC.Message.TLdeserialize(data2, data2.readInt32(false), false);
data = cursor.byteBufferValue(15);
if (data != null) {
message.replyMessage = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (message.replyMessage != null) {
addUsersAndChatsFromMessage(message.replyMessage, usersToLoad, chatsToLoad);
}
}
data2.reuse();
}
if (message.replyMessage == null) {
long messageId = message.reply_to_msg_id;
@ -5388,7 +5463,6 @@ public class MessagesStorage {
}
}
}
data.reuse();
int lower_id = (int)dialog.id;
int high_id = (int)(dialog.id >> 32);
@ -5419,9 +5493,10 @@ public class MessagesStorage {
if (!replyMessages.isEmpty()) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid, date, uid FROM messages WHERE mid IN(%s)", TextUtils.join(",", replyMessages)));
while (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
message.id = cursor.intValue(1);
message.date = cursor.intValue(2);
message.dialog_id = cursor.longValue(3);
@ -5434,7 +5509,6 @@ public class MessagesStorage {
message.dialog_id = owner.dialog_id;
}
}
data.reuse();
}
cursor.dispose();
}
@ -5709,7 +5783,7 @@ public class MessagesStorage {
});
}
public int getChannelReadInboxMax(final int channelId) {
public int getDialogReadInboxMax(final long dialog_id) {
final Semaphore semaphore = new Semaphore(0);
final Integer[] max = new Integer[] {0};
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@ -5717,7 +5791,7 @@ public class MessagesStorage {
public void run() {
SQLiteCursor cursor = null;
try {
cursor = database.queryFinalized("SELECT inbox_max FROM dialogs WHERE did = " + (-channelId));
cursor = database.queryFinalized("SELECT inbox_max FROM dialogs WHERE did = " + dialog_id);
if (cursor.next()) {
max[0] = cursor.intValue(0);
}

View file

@ -0,0 +1,593 @@
/*
* This is the source code of Telegram for Android v. 3.x.x.
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Nikolai Kudashov, 2013-2016.
*/
package org.telegram.messenger;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.media.MediaDescription;
import android.media.MediaMetadata;
import android.media.browse.MediaBrowser;
import android.media.session.MediaSession;
import android.media.session.PlaybackState;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Process;
import android.os.SystemClock;
import android.service.media.MediaBrowserService;
import android.text.TextUtils;
import org.telegram.SQLite.SQLiteCursor;
import org.telegram.messenger.audioinfo.AudioInfo;
import org.telegram.messenger.query.SharedMediaQuery;
import org.telegram.tgnet.NativeByteBuffer;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.LaunchActivity;
import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class MusicBrowserService extends MediaBrowserService implements NotificationCenter.NotificationCenterDelegate {
private static final String AUTO_APP_PACKAGE_NAME = "com.google.android.projection.gearhead";
private static final String SLOT_RESERVATION_SKIP_TO_NEXT = "com.google.android.gms.car.media.ALWAYS_RESERVE_SPACE_FOR.ACTION_SKIP_TO_NEXT";
private static final String SLOT_RESERVATION_SKIP_TO_PREV = "com.google.android.gms.car.media.ALWAYS_RESERVE_SPACE_FOR.ACTION_SKIP_TO_PREVIOUS";
private static final String SLOT_RESERVATION_QUEUE = "com.google.android.gms.car.media.ALWAYS_RESERVE_SPACE_FOR.ACTION_QUEUE";
private MediaSession mediaSession;
private static final String MEDIA_ID_ROOT = "__ROOT__";
private boolean chatsLoaded;
private boolean loadingChats;
private ArrayList<Integer> dialogs = new ArrayList<>();
private HashMap<Integer, TLRPC.User> users = new HashMap<>();
private HashMap<Integer, TLRPC.Chat> chats = new HashMap<>();
private HashMap<Integer, ArrayList<MessageObject>> musicObjects = new HashMap<>();
private HashMap<Integer, ArrayList<MediaSession.QueueItem>> musicQueues = new HashMap<>();
public static final String ACTION_CMD = "com.example.android.mediabrowserservice.ACTION_CMD";
public static final String CMD_NAME = "CMD_NAME";
public static final String CMD_PAUSE = "CMD_PAUSE";
private Paint roundPaint;
private RectF bitmapRect;
private boolean serviceStarted;
private int lastSelectedDialog;
private static final int STOP_DELAY = 30000;
private DelayedStopHandler delayedStopHandler = new DelayedStopHandler(this);
@Override
public void onCreate() {
super.onCreate();
ApplicationLoader.postInitApplication();
lastSelectedDialog = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE).getInt("auto_lastSelectedDialog", 0);
mediaSession = new MediaSession(this, "MusicService");
setSessionToken(mediaSession.getSessionToken());
mediaSession.setCallback(new MediaSessionCallback());
mediaSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS | MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
Context context = getApplicationContext();
Intent intent = new Intent(context, LaunchActivity.class);
PendingIntent pi = PendingIntent.getActivity(context, 99, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mediaSession.setSessionActivity(pi);
Bundle extras = new Bundle();
extras.putBoolean(SLOT_RESERVATION_QUEUE, true);
extras.putBoolean(SLOT_RESERVATION_SKIP_TO_PREV, true);
extras.putBoolean(SLOT_RESERVATION_SKIP_TO_NEXT, true);
mediaSession.setExtras(extras);
updatePlaybackState(null);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.audioPlayStateChanged);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.audioDidStarted);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.audioDidReset);
}
@Override
public int onStartCommand(Intent startIntent, int flags, int startId) {
/*if (startIntent != null) {
String action = startIntent.getAction();
String command = startIntent.getStringExtra(CMD_NAME);
if (ACTION_CMD.equals(action)) {
if (CMD_PAUSE.equals(command)) {
if (mPlayback != null && mPlayback.isPlaying()) {
handlePauseRequest();
}
}
}
}*/
return START_STICKY;
}
@Override
public void onDestroy() {
handleStopRequest(null);
delayedStopHandler.removeCallbacksAndMessages(null);
mediaSession.release();
}
@Override
public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) {
if (clientPackageName == null || Process.SYSTEM_UID != clientUid && Process.myUid() != clientUid && !clientPackageName.equals("com.google.android.mediasimulator") && !clientPackageName.equals("com.google.android.projection.gearhead")) {
return null;
}
return new BrowserRoot(MEDIA_ID_ROOT, null);
}
@Override
public void onLoadChildren(final String parentMediaId, final Result<List<MediaBrowser.MediaItem>> result) {
if (!chatsLoaded) {
result.detach();
if (loadingChats) {
return;
}
loadingChats = true;
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
try {
ArrayList<Integer> usersToLoad = new ArrayList<>();
ArrayList<Integer> chatsToLoad = new ArrayList<>();
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT DISTINCT uid FROM media_v2 WHERE uid != 0 AND mid > 0 AND type = %d", SharedMediaQuery.MEDIA_MUSIC));
while (cursor.next()) {
int lower_part = (int) cursor.longValue(0);
if (lower_part == 0) {
continue;
}
dialogs.add(lower_part);
if (lower_part > 0) {
usersToLoad.add(lower_part);
} else {
chatsToLoad.add(-lower_part);
}
}
cursor.dispose();
if (!dialogs.isEmpty()) {
String ids = TextUtils.join(",", dialogs);
cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT uid, data, mid FROM media_v2 WHERE uid IN (%s) AND mid > 0 AND type = %d ORDER BY date DESC, mid DESC", ids, SharedMediaQuery.MEDIA_MUSIC));
while (cursor.next()) {
NativeByteBuffer data = cursor.byteBufferValue(1);
if (data != null) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (MessageObject.isMusicMessage(message)) {
int did = cursor.intValue(0);
message.id = cursor.intValue(2);
message.dialog_id = did;
ArrayList<MessageObject> arrayList = musicObjects.get(did);
ArrayList<MediaSession.QueueItem> arrayList1 = musicQueues.get(did);
if (arrayList == null) {
arrayList = new ArrayList<>();
musicObjects.put(did, arrayList);
arrayList1 = new ArrayList<>();
musicQueues.put(did, arrayList1);
}
MessageObject messageObject = new MessageObject(message, null, false);
arrayList.add(0, messageObject);
MediaDescription.Builder builder = new MediaDescription.Builder().setMediaId(did + "_" + arrayList.size());
builder.setTitle(messageObject.getMusicTitle());
builder.setSubtitle(messageObject.getMusicAuthor());
arrayList1.add(0, new MediaSession.QueueItem(builder.build(), arrayList1.size()));
}
}
}
cursor.dispose();
if (!usersToLoad.isEmpty()) {
ArrayList<TLRPC.User> usersArrayList = new ArrayList<>();
MessagesStorage.getInstance().getUsersInternal(TextUtils.join(",", usersToLoad), usersArrayList);
for (int a = 0; a < usersArrayList.size(); a++) {
TLRPC.User user = usersArrayList.get(a);
users.put(user.id, user);
}
}
if (!chatsToLoad.isEmpty()) {
ArrayList<TLRPC.Chat> chatsArrayList = new ArrayList<>();
MessagesStorage.getInstance().getChatsInternal(TextUtils.join(",", chatsToLoad), chatsArrayList);
for (int a = 0; a < chatsArrayList.size(); a++) {
TLRPC.Chat chat = chatsArrayList.get(a);
chats.put(chat.id, chat);
}
}
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
chatsLoaded = true;
loadingChats = false;
loadChildrenImpl(parentMediaId, result);
if (lastSelectedDialog == 0 && !dialogs.isEmpty()) {
lastSelectedDialog = dialogs.get(0);
}
if (lastSelectedDialog != 0) {
ArrayList<MessageObject> arrayList = musicObjects.get(lastSelectedDialog);
ArrayList<MediaSession.QueueItem> arrayList1 = musicQueues.get(lastSelectedDialog);
if (arrayList != null && !arrayList.isEmpty()) {
mediaSession.setQueue(arrayList1);
if (lastSelectedDialog > 0) {
TLRPC.User user = users.get(lastSelectedDialog);
if (user != null) {
mediaSession.setQueueTitle(ContactsController.formatName(user.first_name, user.last_name));
} else {
mediaSession.setQueueTitle("DELETED USER");
}
} else {
TLRPC.Chat chat = chats.get(-lastSelectedDialog);
if (chat != null) {
mediaSession.setQueueTitle(chat.title);
} else {
mediaSession.setQueueTitle("DELETED CHAT");
}
}
MessageObject messageObject = arrayList.get(0);
MediaMetadata.Builder builder = new MediaMetadata.Builder();
builder.putLong(MediaMetadata.METADATA_KEY_DURATION, messageObject.getDuration() * 1000);
builder.putString(MediaMetadata.METADATA_KEY_ARTIST, messageObject.getMusicAuthor());
builder.putString(MediaMetadata.METADATA_KEY_TITLE, messageObject.getMusicTitle());
mediaSession.setMetadata(builder.build());
}
}
updatePlaybackState(null);
}
});
}
});
} else {
loadChildrenImpl(parentMediaId, result);
}
}
private void loadChildrenImpl(final String parentMediaId, final Result<List<MediaBrowser.MediaItem>> result) {
List<MediaBrowser.MediaItem> mediaItems = new ArrayList<>();
if (MEDIA_ID_ROOT.equals(parentMediaId)) {
for (int a = 0; a < dialogs.size(); a++) {
int did = dialogs.get(a);
MediaDescription.Builder builder = new MediaDescription.Builder().setMediaId("__CHAT_" + did);
TLRPC.FileLocation avatar = null;
if (did > 0) {
TLRPC.User user = users.get(did);
if (user != null) {
builder.setTitle(ContactsController.formatName(user.first_name, user.last_name));
if (user.photo != null && user.photo.photo_small instanceof TLRPC.TL_fileLocation) {
avatar = user.photo.photo_small;
}
} else {
builder.setTitle("DELETED USER");
}
} else {
TLRPC.Chat chat = chats.get(-did);
if (chat != null) {
builder.setTitle(chat.title);
if (chat.photo != null && chat.photo.photo_small instanceof TLRPC.TL_fileLocation) {
avatar = chat.photo.photo_small;
}
} else {
builder.setTitle("DELETED CHAT");
}
}
Bitmap bitmap = null;
if (avatar != null) {
bitmap = createRoundBitmap(FileLoader.getPathToAttach(avatar, true));
if (bitmap != null) {
builder.setIconBitmap(bitmap);
}
}
if (avatar == null || bitmap == null) {
builder.setIconUri(Uri.parse("android.resource://" + getApplicationContext().getPackageName() + "/drawable/contact_blue"));
}
mediaItems.add(new MediaBrowser.MediaItem(builder.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE));
}
} else if (parentMediaId != null && parentMediaId.startsWith("__CHAT_")) {
int did = 0;
try {
did = Integer.parseInt(parentMediaId.replace("__CHAT_", ""));
} catch (Exception e) {
FileLog.e("tmessages", e);
}
ArrayList<MessageObject> arrayList = musicObjects.get(did);
if (arrayList != null) {
for (int a = 0; a < arrayList.size(); a++) {
MessageObject messageObject = arrayList.get(a);
MediaDescription.Builder builder = new MediaDescription.Builder().setMediaId(did + "_" + a);
builder.setTitle(messageObject.getMusicTitle());
builder.setSubtitle(messageObject.getMusicAuthor());
mediaItems.add(new MediaBrowser.MediaItem(builder.build(), MediaBrowser.MediaItem.FLAG_PLAYABLE));
}
}
}
result.sendResult(mediaItems);
}
private Bitmap createRoundBitmap(File path) {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap bitmap = BitmapFactory.decodeFile(path.toString(), options);
if (bitmap != null) {
Bitmap result = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
result.eraseColor(Color.TRANSPARENT);
Canvas canvas = new Canvas(result);
BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
if (roundPaint == null) {
roundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
bitmapRect = new RectF();
}
roundPaint.setShader(shader);
bitmapRect.set(0, 0, bitmap.getWidth(), bitmap.getHeight());
canvas.drawRoundRect(bitmapRect, bitmap.getWidth(), bitmap.getHeight(), roundPaint);
return result;
}
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
return null;
}
private final class MediaSessionCallback extends MediaSession.Callback {
@Override
public void onPlay() {
MessageObject messageObject = MediaController.getInstance().getPlayingMessageObject();
if (messageObject == null) {
onPlayFromMediaId(lastSelectedDialog + "_" + 0, null);
} else {
MediaController.getInstance().playAudio(messageObject);
}
}
@Override
public void onSkipToQueueItem(long queueId) {
MediaController.getInstance().playMessageAtIndex((int) queueId);
handlePlayRequest();
}
@Override
public void onSeekTo(long position) {
MessageObject messageObject = MediaController.getInstance().getPlayingMessageObject();
if (messageObject != null) {
MediaController.getInstance().seekToProgress(messageObject, position / 1000 / (float) messageObject.getDuration());
}
}
@Override
public void onPlayFromMediaId(String mediaId, Bundle extras) {
String args[] = mediaId.split("_");
if (args.length != 2) {
return;
}
try {
int did = Integer.parseInt(args[0]);
int id = Integer.parseInt(args[1]);
ArrayList<MessageObject> arrayList = musicObjects.get(did);
ArrayList<MediaSession.QueueItem> arrayList1 = musicQueues.get(did);
if (arrayList == null || id < 0 || id >= arrayList.size()) {
return;
}
lastSelectedDialog = did;
ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE).edit().putInt("auto_lastSelectedDialog", did).commit();
MediaController.getInstance().setPlaylist(arrayList, arrayList.get(id), false);
mediaSession.setQueue(arrayList1);
if (did > 0) {
TLRPC.User user = users.get(did);
if (user != null) {
mediaSession.setQueueTitle(ContactsController.formatName(user.first_name, user.last_name));
} else {
mediaSession.setQueueTitle("DELETED USER");
}
} else {
TLRPC.Chat chat = chats.get(-did);
if (chat != null) {
mediaSession.setQueueTitle(chat.title);
} else {
mediaSession.setQueueTitle("DELETED CHAT");
}
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
handlePlayRequest();
}
@Override
public void onPause() {
handlePauseRequest();
}
@Override
public void onStop() {
handleStopRequest(null);
}
@Override
public void onSkipToNext() {
MediaController.getInstance().playNextMessage();
}
@Override
public void onSkipToPrevious() {
MediaController.getInstance().playPreviousMessage();
}
@Override
public void onPlayFromSearch(String query, Bundle extras) {
if (query == null || query.length() == 0) {
return;
}
query = query.toLowerCase();
for (int a = 0; a < dialogs.size(); a++) {
int did = dialogs.get(a);
if (did > 0) {
TLRPC.User user = users.get(did);
if (user == null) {
continue;
}
if (user.first_name != null && user.first_name.startsWith(query) || user.last_name != null && user.last_name.startsWith(query)) {
onPlayFromMediaId(did + "_" + 0, null);
break;
}
} else {
TLRPC.Chat chat = chats.get(-did);
if (chat == null) {
continue;
}
if (chat.title != null && chat.title.toLowerCase().contains(query)) {
onPlayFromMediaId(did + "_" + 0, null);
break;
}
}
}
}
}
private void updatePlaybackState(String error) {
long position = PlaybackState.PLAYBACK_POSITION_UNKNOWN;
MessageObject playingMessageObject = MediaController.getInstance().getPlayingMessageObject();
if (playingMessageObject != null) {
position = playingMessageObject.audioProgressSec * 1000;
}
PlaybackState.Builder stateBuilder = new PlaybackState.Builder().setActions(getAvailableActions());
int state;
if (playingMessageObject == null) {
state = PlaybackState.STATE_STOPPED;
} else {
if (MediaController.getInstance().isDownloadingCurrentMessage()) {
state = PlaybackState.STATE_BUFFERING;
} else {
state = MediaController.getInstance().isAudioPaused() ? PlaybackState.STATE_PAUSED : PlaybackState.STATE_PLAYING;
}
}
if (error != null) {
stateBuilder.setErrorMessage(error);
state = PlaybackState.STATE_ERROR;
}
stateBuilder.setState(state, position, 1.0f, SystemClock.elapsedRealtime());
if (playingMessageObject != null) {
stateBuilder.setActiveQueueItemId(MediaController.getInstance().getPlayingMessageObjectNum());
} else {
stateBuilder.setActiveQueueItemId(0);
}
mediaSession.setPlaybackState(stateBuilder.build());
}
private long getAvailableActions() {
long actions = PlaybackState.ACTION_PLAY | PlaybackState.ACTION_PLAY_FROM_MEDIA_ID | PlaybackState.ACTION_PLAY_FROM_SEARCH;
MessageObject playingMessageObject = MediaController.getInstance().getPlayingMessageObject();
if (playingMessageObject != null) {
if (!MediaController.getInstance().isAudioPaused()) {
actions |= PlaybackState.ACTION_PAUSE;
}
actions |= PlaybackState.ACTION_SKIP_TO_PREVIOUS;
actions |= PlaybackState.ACTION_SKIP_TO_NEXT;
}
return actions;
}
private void handleStopRequest(String withError) {
delayedStopHandler.removeCallbacksAndMessages(null);
delayedStopHandler.sendEmptyMessageDelayed(0, STOP_DELAY);
updatePlaybackState(withError);
stopSelf();
serviceStarted = false;
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.audioPlayStateChanged);
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.audioDidStarted);
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.audioDidReset);
}
private void handlePlayRequest() {
delayedStopHandler.removeCallbacksAndMessages(null);
if (!serviceStarted) {
startService(new Intent(getApplicationContext(), MusicBrowserService.class));
serviceStarted = true;
}
if (!mediaSession.isActive()) {
mediaSession.setActive(true);
}
MessageObject messageObject = MediaController.getInstance().getPlayingMessageObject();
if (messageObject == null) {
return;
}
MediaMetadata.Builder builder = new MediaMetadata.Builder();
builder.putLong(MediaMetadata.METADATA_KEY_DURATION, messageObject.getDuration() * 1000);
builder.putString(MediaMetadata.METADATA_KEY_ARTIST, messageObject.getMusicAuthor());
builder.putString(MediaMetadata.METADATA_KEY_TITLE, messageObject.getMusicTitle());
AudioInfo audioInfo = MediaController.getInstance().getAudioInfo();
if (audioInfo != null) {
Bitmap bitmap = audioInfo.getCover();
if (bitmap != null) {
builder.putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, bitmap);
}
}
mediaSession.setMetadata(builder.build());
}
private void handlePauseRequest() {
MediaController.getInstance().pauseAudio(MediaController.getInstance().getPlayingMessageObject());
delayedStopHandler.removeCallbacksAndMessages(null);
delayedStopHandler.sendEmptyMessageDelayed(0, STOP_DELAY);
}
@Override
public void didReceivedNotification(int id, Object... args) {
updatePlaybackState(null);
handlePlayRequest();
}
private static class DelayedStopHandler extends Handler {
private final WeakReference<MusicBrowserService> mWeakReference;
private DelayedStopHandler(MusicBrowserService service) {
mWeakReference = new WeakReference<>(service);
}
@Override
public void handleMessage(Message msg) {
MusicBrowserService service = mWeakReference.get();
if (service != null) {
MessageObject messageObject = MediaController.getInstance().getPlayingMessageObject();
if (messageObject != null && !MediaController.getInstance().isAudioPaused()) {
return;
}
service.stopSelf();
service.serviceStarted = false;
}
}
}
}

View file

@ -37,7 +37,6 @@ public class NativeCrashManager {
try {
String filename = UUID.randomUUID().toString();
String path = Constants.FILES_PATH + "/" + filename + ".faketrace";
Log.d(Constants.TAG, "Writing unhandled exception to: " + path);
BufferedWriter write = new BufferedWriter(new FileWriter(path));
write.write("Package: " + Constants.APP_PACKAGE + "\n");
write.write("Version Code: " + Constants.APP_VERSION + "\n");
@ -114,7 +113,6 @@ public class NativeCrashManager {
};
return dir.list(filter);
} else {
FileLog.d(Constants.TAG, "Can't search for exception as file path is null.");
return new String[0];
}
}

View file

@ -23,7 +23,7 @@ import java.util.zip.ZipFile;
public class NativeLoader {
private final static int LIB_VERSION = 21;
private final static int LIB_VERSION = 22;
private final static String LIB_NAME = "tmessages." + LIB_VERSION;
private final static String LIB_SO_NAME = "lib" + LIB_NAME + ".so";
private final static String LOCALE_LIB_SO_NAME = "lib" + LIB_NAME + "loc.so";
@ -77,11 +77,9 @@ public class NativeLoader {
}
out.close();
if (Build.VERSION.SDK_INT >= 9) {
destLocalFile.setReadable(true, false);
destLocalFile.setExecutable(true, false);
destLocalFile.setWritable(true);
}
destLocalFile.setReadable(true, false);
destLocalFile.setExecutable(true, false);
destLocalFile.setWritable(true);
try {
System.load(destLocalFile.getAbsolutePath());

View file

@ -71,6 +71,8 @@ public class NotificationCenter {
public static final int locationPermissionGranted = totalEvents++;
public static final int peerSettingsDidLoaded = totalEvents++;
public static final int wasUnableToFindCurrentLocation = totalEvents++;
public static final int reloadHints = totalEvents++;
public static final int reloadInlineHints = totalEvents++;
public static final int httpFileDidLoaded = totalEvents++;
public static final int httpFileDidFailedLoad = totalEvents++;
@ -162,6 +164,10 @@ public class NotificationCenter {
}
}
public boolean isAnimationInProgress() {
return animationInProgress;
}
public void postNotificationName(int id, Object... args) {
boolean allowDuringAnimation = false;
if (allowedNotifications != null) {

View file

@ -769,7 +769,12 @@ public class NotificationsController {
msg = LocaleController.formatString("NotificationMessageMap", R.string.NotificationMessageMap, name);
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) {
if (messageObject.isSticker()) {
msg = LocaleController.formatString("NotificationMessageSticker", R.string.NotificationMessageSticker, name);
String emoji = messageObject.getStickerEmoji();
if (emoji != null) {
msg = LocaleController.formatString("NotificationMessageStickerEmoji", R.string.NotificationMessageStickerEmoji, name, emoji);
} else {
msg = LocaleController.formatString("NotificationMessageSticker", R.string.NotificationMessageSticker, name);
}
} else if (messageObject.isGif()) {
msg = LocaleController.formatString("NotificationMessageGif", R.string.NotificationMessageGif, name);
} else {
@ -889,10 +894,19 @@ public class NotificationsController {
msg = LocaleController.formatString("NotificationActionPinnedVoiceChannel", R.string.NotificationActionPinnedVoiceChannel, chat.title);
}
} else if (object.isSticker()) {
if (!ChatObject.isChannel(chat) || chat.megagroup) {
msg = LocaleController.formatString("NotificationActionPinnedSticker", R.string.NotificationActionPinnedSticker, name, chat.title);
String emoji = messageObject.getStickerEmoji();
if (emoji != null) {
if (!ChatObject.isChannel(chat) || chat.megagroup) {
msg = LocaleController.formatString("NotificationActionPinnedStickerEmoji", R.string.NotificationActionPinnedStickerEmoji, name, chat.title, emoji);
} else {
msg = LocaleController.formatString("NotificationActionPinnedStickerEmojiChannel", R.string.NotificationActionPinnedStickerEmojiChannel, chat.title, emoji);
}
} else {
msg = LocaleController.formatString("NotificationActionPinnedStickerChannel", R.string.NotificationActionPinnedStickerChannel, chat.title);
if (!ChatObject.isChannel(chat) || chat.megagroup) {
msg = LocaleController.formatString("NotificationActionPinnedSticker", R.string.NotificationActionPinnedSticker, name, chat.title);
} else {
msg = LocaleController.formatString("NotificationActionPinnedStickerChannel", R.string.NotificationActionPinnedStickerChannel, chat.title);
}
}
} else if (object.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) {
if (!ChatObject.isChannel(chat) || chat.megagroup) {
@ -960,7 +974,12 @@ public class NotificationsController {
msg = LocaleController.formatString("ChannelMessageMap", R.string.ChannelMessageMap, name, chat.title);
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) {
if (messageObject.isSticker()) {
msg = LocaleController.formatString("ChannelMessageSticker", R.string.ChannelMessageSticker, name, chat.title);
String emoji = messageObject.getStickerEmoji();
if (emoji != null) {
msg = LocaleController.formatString("ChannelMessageStickerEmoji", R.string.ChannelMessageStickerEmoji, name, chat.title, emoji);
} else {
msg = LocaleController.formatString("ChannelMessageSticker", R.string.ChannelMessageSticker, name, chat.title);
}
} else if (messageObject.isGif()) {
msg = LocaleController.formatString("ChannelMessageGIF", R.string.ChannelMessageGIF, name, chat.title);
} else {
@ -988,7 +1007,12 @@ public class NotificationsController {
msg = LocaleController.formatString("ChannelMessageGroupMap", R.string.ChannelMessageGroupMap, name, chat.title);
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) {
if (messageObject.isSticker()) {
msg = LocaleController.formatString("ChannelMessageGroupSticker", R.string.ChannelMessageGroupSticker, name, chat.title);
String emoji = messageObject.getStickerEmoji();
if (emoji != null) {
msg = LocaleController.formatString("ChannelMessageGroupStickerEmoji", R.string.ChannelMessageGroupStickerEmoji, name, chat.title, emoji);
} else {
msg = LocaleController.formatString("ChannelMessageGroupSticker", R.string.ChannelMessageGroupSticker, name, chat.title);
}
} else if (messageObject.isGif()) {
msg = LocaleController.formatString("ChannelMessageGroupGif", R.string.ChannelMessageGroupGif, name, chat.title);
} else {
@ -1017,7 +1041,12 @@ public class NotificationsController {
msg = LocaleController.formatString("NotificationMessageGroupMap", R.string.NotificationMessageGroupMap, name, chat.title);
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) {
if (messageObject.isSticker()) {
msg = LocaleController.formatString("NotificationMessageGroupSticker", R.string.NotificationMessageGroupSticker, name, chat.title);
String emoji = messageObject.getStickerEmoji();
if (emoji != null) {
msg = LocaleController.formatString("NotificationMessageGroupStickerEmoji", R.string.NotificationMessageGroupStickerEmoji, name, chat.title, emoji);
} else {
msg = LocaleController.formatString("NotificationMessageGroupSticker", R.string.NotificationMessageGroupSticker, name, chat.title);
}
} else if (messageObject.isGif()) {
msg = LocaleController.formatString("NotificationMessageGroupGif", R.string.NotificationMessageGroupGif, name, chat.title);
} else {

View file

@ -0,0 +1,36 @@
/*
* This is the source code of Telegram for Android v. 3.x.x.
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Nikolai Kudashov, 2013-2016.
*/
package org.telegram.messenger;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import org.telegram.ui.LaunchActivity;
public class OpenChatReceiver extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
if (intent == null) {
finish();
}
if (intent.getAction() == null || !intent.getAction().startsWith("com.tmessages.openchat")) {
finish();
return;
}
Intent intent2 = new Intent(this, LaunchActivity.class);
intent2.setAction(intent.getAction());
intent2.putExtras(intent);
startActivity(intent2);
finish();
}
}

View file

@ -176,7 +176,7 @@ public class SecretChatHelper {
}
reqSend.random_id = message.random_id;
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null);
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null, null);
}
protected void processUpdateEncryption(TLRPC.TL_updateEncryption update, ConcurrentHashMap<Integer, TLRPC.User> usersDict) {
@ -281,7 +281,7 @@ public class SecretChatHelper {
}
reqSend.random_id = message.random_id;
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null);
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null, null);
}
public void sendClearHistoryMessage(TLRPC.EncryptedChat encryptedChat, TLRPC.Message resendMessage) {
@ -308,7 +308,7 @@ public class SecretChatHelper {
}
reqSend.random_id = message.random_id;
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null);
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null, null);
}
public void sendNotifyLayerMessage(final TLRPC.EncryptedChat encryptedChat, TLRPC.Message resendMessage) {
@ -340,7 +340,7 @@ public class SecretChatHelper {
}
reqSend.random_id = message.random_id;
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null);
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null, null);
}
public void sendRequestKeyMessage(final TLRPC.EncryptedChat encryptedChat, TLRPC.Message resendMessage) {
@ -371,7 +371,7 @@ public class SecretChatHelper {
}
reqSend.random_id = message.random_id;
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null);
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null, null);
}
public void sendAcceptKeyMessage(final TLRPC.EncryptedChat encryptedChat, TLRPC.Message resendMessage) {
@ -403,7 +403,7 @@ public class SecretChatHelper {
}
reqSend.random_id = message.random_id;
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null);
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null, null);
}
public void sendCommitKeyMessage(final TLRPC.EncryptedChat encryptedChat, TLRPC.Message resendMessage) {
@ -434,7 +434,7 @@ public class SecretChatHelper {
}
reqSend.random_id = message.random_id;
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null);
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null, null);
}
public void sendAbortKeyMessage(final TLRPC.EncryptedChat encryptedChat, TLRPC.Message resendMessage, long excange_id) {
@ -464,7 +464,7 @@ public class SecretChatHelper {
}
reqSend.random_id = message.random_id;
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null);
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null, null);
}
public void sendNoopMessage(final TLRPC.EncryptedChat encryptedChat, TLRPC.Message resendMessage) {
@ -492,7 +492,7 @@ public class SecretChatHelper {
}
reqSend.random_id = message.random_id;
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null);
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null, null);
}
public void sendTTLMessage(TLRPC.EncryptedChat encryptedChat, TLRPC.Message resendMessage) {
@ -528,7 +528,7 @@ public class SecretChatHelper {
}
reqSend.random_id = message.random_id;
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null);
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null, null);
}
public void sendScreenshotMessage(TLRPC.EncryptedChat encryptedChat, ArrayList<Long> random_ids, TLRPC.Message resendMessage) {
@ -564,10 +564,11 @@ public class SecretChatHelper {
}
reqSend.random_id = message.random_id;
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null);
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null, null);
}
private void processSentMessage(TLRPC.Message newMsg, TLRPC.EncryptedFile file, TLRPC.DecryptedMessage decryptedMessage, String originalPath) {
private void updateMediaPaths(MessageObject newMsgObj, TLRPC.EncryptedFile file, TLRPC.DecryptedMessage decryptedMessage, String originalPath) {
TLRPC.Message newMsg = newMsgObj.messageOwner;
if (file != null) {
if (newMsg.media instanceof TLRPC.TL_messageMediaPhoto && newMsg.media.photo != null) {
TLRPC.PhotoSize size = newMsg.media.photo.sizes.get(newMsg.media.photo.sizes.size() - 1);
@ -608,6 +609,8 @@ public class SecretChatHelper {
File cacheFile = new File(newMsg.attachPath);
File cacheFile2 = FileLoader.getPathToAttach(newMsg.media.document);
if (cacheFile.renameTo(cacheFile2)) {
newMsgObj.mediaExists = newMsgObj.attachPathExists;
newMsgObj.attachPathExists = false;
newMsg.attachPath = "";
}
}
@ -640,7 +643,7 @@ public class SecretChatHelper {
return message.action instanceof TLRPC.TL_messageEncryptedAction && !(message.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages || message.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL);
}
protected void performSendEncryptedRequest(final TLRPC.DecryptedMessage req, final TLRPC.Message newMsgObj, final TLRPC.EncryptedChat chat, final TLRPC.InputEncryptedFile encryptedFile, final String originalPath) {
protected void performSendEncryptedRequest(final TLRPC.DecryptedMessage req, final TLRPC.Message newMsgObj, final TLRPC.EncryptedChat chat, final TLRPC.InputEncryptedFile encryptedFile, final String originalPath, final MessageObject newMsg) {
if (req == null || chat.auth_key == null || chat instanceof TLRPC.TL_encryptedChatRequested || chat instanceof TLRPC.TL_encryptedChatWaiting) {
return;
}
@ -800,8 +803,8 @@ public class SecretChatHelper {
if (isSecretVisibleMessage(newMsgObj)) {
newMsgObj.date = res.date;
}
if (res.file instanceof TLRPC.TL_encryptedFile) {
processSentMessage(newMsgObj, res.file, req, originalPath);
if (newMsg != null && res.file instanceof TLRPC.TL_encryptedFile) {
updateMediaPaths(newMsg, res.file, req, originalPath);
}
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
@ -1042,7 +1045,7 @@ public class SecretChatHelper {
newMessage.media.document.attributes = decryptedMessage.media.attributes;
}
newMessage.media.document.mime_type = decryptedMessage.media.mime_type;
newMessage.media.document.size = file.size;
newMessage.media.document.size = decryptedMessage.media.size != 0 ? Math.min(decryptedMessage.media.size, file.size) : file.size;
newMessage.media.document.key = decryptedMessage.media.key;
newMessage.media.document.iv = decryptedMessage.media.iv;
if (newMessage.media.document.mime_type == null) {

View file

@ -10,9 +10,7 @@ package org.telegram.messenger;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.location.Location;
@ -29,6 +27,7 @@ import android.webkit.MimeTypeMap;
import android.widget.Toast;
import org.telegram.messenger.audioinfo.AudioInfo;
import org.telegram.messenger.query.SearchQuery;
import org.telegram.messenger.query.StickersQuery;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.QuickAckDelegate;
@ -306,7 +305,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
message.sendEncryptedRequest.media.key = (byte[]) args[3];
message.sendEncryptedRequest.media.iv = (byte[]) args[4];
SecretChatHelper.getInstance().performSendEncryptedRequest(message.sendEncryptedRequest, message.obj.messageOwner, message.encryptedChat, encryptedFile, message.originalPath);
SecretChatHelper.getInstance().performSendEncryptedRequest(message.sendEncryptedRequest, message.obj.messageOwner, message.encryptedChat, encryptedFile, message.originalPath, message.obj);
arr.remove(a);
a--;
}
@ -892,6 +891,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
@Override
public void run() {
newMsgObj.send_state = MessageObject.MESSAGE_SEND_STATE_SENT;
SearchQuery.increasePeerRaiting(peer);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByServer, oldId, newMsgObj.id, newMsgObj, peer);
processSentMessage(oldId);
removeFromSendingMessages(oldId);
@ -945,14 +945,10 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
}
public void editMessage(MessageObject messageObject, String message, boolean searchLinks, final BaseFragment fragment) {
if (fragment == null || fragment.getParentActivity() == null) {
return;
public int editMessage(MessageObject messageObject, String message, boolean searchLinks, final BaseFragment fragment, ArrayList<TLRPC.MessageEntity> entities, final Runnable callback) {
if (fragment == null || fragment.getParentActivity() == null || callback == null) {
return 0;
}
final ProgressDialog progressDialog = new ProgressDialog(fragment.getParentActivity());
progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading));
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setCancelable(false);
TLRPC.TL_messages_editMessage req = new TLRPC.TL_messages_editMessage();
req.peer = MessagesController.getInputPeer((int) messageObject.getDialogId());
@ -960,19 +956,17 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
req.flags |= 2048;
req.id = messageObject.getId();
req.no_webpage = !searchLinks;
final int reqId = ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
if (entities != null) {
req.entities = entities;
req.flags |= 8;
}
return ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
@Override
public void run(TLObject response, TLRPC.TL_error error) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
try {
if (!fragment.getParentActivity().isFinishing()) {
progressDialog.dismiss();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
callback.run();
}
});
if (error == null) {
@ -993,22 +987,6 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
}
});
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, LocaleController.getString("Cancel", R.string.Cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ConnectionsManager.getInstance().cancelRequest(reqId, true);
try {
dialog.dismiss();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
try {
progressDialog.show();
} catch (Exception e) {
//don't promt
}
}
private void sendLocation(Location location) {
@ -1451,9 +1429,12 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
newMsg.media_unread = true;
}
newMsg.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING;
newMsgObj = new MessageObject(newMsg, null, true);
newMsgObj.replyMessageObject = reply_to_msg;
newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING;
if (!newMsgObj.isForwarded() && newMsgObj.type == 3) {
newMsgObj.attachPathExists = true;
}
ArrayList<MessageObject> objArr = new ArrayList<>();
objArr.add(newMsgObj);
@ -1500,6 +1481,10 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
if (!searchLinks) {
reqSend.no_webpage = true;
}
if (entities != null && !entities.isEmpty()) {
reqSend.entities = entities;
reqSend.flags |= 8;
}
performSendMessageRequest(reqSend, newMsgObj, null);
}
} else {
@ -1536,7 +1521,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
} else {
reqSend.media = new TLRPC.TL_decryptedMessageMediaEmpty();
}
SecretChatHelper.getInstance().performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, null, null);
SecretChatHelper.getInstance().performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, null, null, newMsgObj);
}
} else if (type >= 1 && type <= 3 || type >= 5 && type <= 8 || type == 9 && encryptedChat != null) {
if (encryptedChat == null) {
@ -1764,7 +1749,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
reqSend.media.lat = location.geo.lat;
reqSend.media._long = location.geo._long;
SecretChatHelper.getInstance().performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, null, null);
SecretChatHelper.getInstance().performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, null, null, newMsgObj);
} else if (type == 2 || type == 9 && photo != null) {
TLRPC.PhotoSize small = photo.sizes.get(0);
TLRPC.PhotoSize big = photo.sizes.get(photo.sizes.size() - 1);
@ -1809,7 +1794,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
encryptedFile.access_hash = big.location.secret;
reqSend.media.key = big.location.key;
reqSend.media.iv = big.location.iv;
SecretChatHelper.getInstance().performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, encryptedFile, null);
SecretChatHelper.getInstance().performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, encryptedFile, null, newMsgObj);
}
} else if (type == 3) {
ImageLoader.fillPhotoSizeWithBytes(document.thumb);
@ -1865,7 +1850,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
encryptedFile.access_hash = document.access_hash;
reqSend.media.key = document.key;
reqSend.media.iv = document.iv;
SecretChatHelper.getInstance().performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, encryptedFile, null);
SecretChatHelper.getInstance().performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, encryptedFile, null, newMsgObj);
}
} else if (type == 6) {
reqSend.media = new TLRPC.TL_decryptedMessageMediaContact();
@ -1873,7 +1858,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
reqSend.media.first_name = user.first_name;
reqSend.media.last_name = user.last_name;
reqSend.media.user_id = user.id;
SecretChatHelper.getInstance().performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, null, null);
SecretChatHelper.getInstance().performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, null, null, newMsgObj);
} else if (type == 7 || type == 9 && document != null) {
if (MessageObject.isStickerDocument(document)) {
reqSend.media = new TLRPC.TL_decryptedMessageMediaExternalDocument();
@ -1890,7 +1875,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
} else {
((TLRPC.TL_decryptedMessageMediaExternalDocument) reqSend.media).thumb = document.thumb;
}
SecretChatHelper.getInstance().performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, null, null);
SecretChatHelper.getInstance().performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, null, null, newMsgObj);
} else {
ImageLoader.fillPhotoSizeWithBytes(document.thumb);
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 46) {
@ -1940,7 +1925,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
encryptedFile.access_hash = document.access_hash;
reqSend.media.key = document.key;
reqSend.media.iv = document.iv;
SecretChatHelper.getInstance().performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, encryptedFile, null);
SecretChatHelper.getInstance().performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, encryptedFile, null, newMsgObj);
}
}
} else if (type == 8) {
@ -2287,6 +2272,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
}
SearchQuery.increasePeerRaiting(newMsgObj.dialog_id);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByServer, oldId, (isBroadcast ? oldId : newMsgObj.id), newMsgObj, newMsgObj.dialog_id);
processSentMessage(oldId);
removeFromSendingMessages(oldId);
@ -2402,7 +2388,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
} else if (size2 != null && MessageObject.isStickerMessage(sentMessage) && size2.location != null) {
size.location = size2.location;
} else if (size2 != null && size2.location instanceof TLRPC.TL_fileLocationUnavailable) {
} else if (size2 != null && size2.location instanceof TLRPC.TL_fileLocationUnavailable || size2 instanceof TLRPC.TL_photoSizeEmpty) {
newMsg.media.document.thumb = sentMessage.media.document.thumb;
}
@ -2414,6 +2400,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
TLRPC.DocumentAttribute attribute = newMsg.media.document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeAudio) {
oldWaveform = attribute.waveform;
break;
}
}
newMsg.media.document.attributes = sentMessage.media.document.attributes;
@ -2439,12 +2426,16 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
if (!cacheFile.renameTo(cacheFile2)) {
sentMessage.attachPath = newMsg.attachPath;
sentMessage.message = newMsg.message;
} else if (!MessageObject.isVideoMessage(sentMessage)) {
newMsgObj.mediaExists = newMsgObj.attachPathExists;
newMsgObj.attachPathExists = false;
newMsg.attachPath = "";
if (originalPath != null && originalPath.startsWith("http")) {
MessagesStorage.getInstance().addRecentLocalFile(originalPath, cacheFile2.toString(), newMsg.media.document);
} else {
if (MessageObject.isVideoMessage(sentMessage)) {
newMsgObj.attachPathExists = true;
} else {
newMsgObj.mediaExists = newMsgObj.attachPathExists;
newMsgObj.attachPathExists = false;
newMsg.attachPath = "";
if (originalPath != null && originalPath.startsWith("http")) {
MessagesStorage.getInstance().addRecentLocalFile(originalPath, cacheFile2.toString(), newMsg.media.document);
}
}
}
} else {
@ -2531,6 +2522,12 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
if ((path == null || path.length() == 0) && uri == null) {
return false;
}
if (uri != null && AndroidUtilities.isInternalUri(uri)) {
return false;
}
if (path != null && AndroidUtilities.isInternalUri(Uri.fromFile(new File(path)))) {
return false;
}
MimeTypeMap myMime = MimeTypeMap.getSingleton();
TLRPC.TL_documentAttributeAudio attributeAudio = null;
if (uri != null) {

View file

@ -180,5 +180,4 @@ public class TgChooserTargetService extends ChooserTargetService {
}
return null;
}
}

View file

@ -41,6 +41,7 @@ public class UserConfig {
public static boolean useFingerprint = true;
public static String lastUpdateVersion;
public static int lastContactsSyncTime;
public static int lastHintsSyncTime;
public static int migrateOffsetId = -1;
public static int migrateOffsetDate = -1;
@ -86,6 +87,7 @@ public class UserConfig {
editor.putString("lastUpdateVersion2", lastUpdateVersion);
editor.putInt("lastContactsSyncTime", lastContactsSyncTime);
editor.putBoolean("useFingerprint", useFingerprint);
editor.putInt("lastHintsSyncTime", lastHintsSyncTime);
editor.putInt("migrateOffsetId", migrateOffsetId);
if (migrateOffsetId != -1) {
@ -226,6 +228,7 @@ public class UserConfig {
useFingerprint = preferences.getBoolean("useFingerprint", true);
lastUpdateVersion = preferences.getString("lastUpdateVersion2", "3.5");
lastContactsSyncTime = preferences.getInt("lastContactsSyncTime", (int) (System.currentTimeMillis() / 1000) - 23 * 60 * 60);
lastHintsSyncTime = preferences.getInt("lastHintsSyncTime", (int) (System.currentTimeMillis() / 1000) - 25 * 60 * 60);
migrateOffsetId = preferences.getInt("migrateOffsetId", 0);
if (migrateOffsetId != -1) {
@ -316,6 +319,7 @@ public class UserConfig {
isWaitingForPasscodeEnter = false;
lastUpdateVersion = BuildVars.BUILD_VERSION_STRING;
lastContactsSyncTime = (int) (System.currentTimeMillis() / 1000) - 23 * 60 * 60;
lastHintsSyncTime = (int) (System.currentTimeMillis() / 1000) - 25 * 60 * 60;
saveConfig(true);
}
}

View file

@ -89,7 +89,11 @@ public class Browser {
public void onServiceConnected(CustomTabsClient client) {
customTabsClient = client;
if (customTabsClient != null) {
customTabsClient.warmup(0);
try {
customTabsClient.warmup(0);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
}

View file

@ -29,6 +29,8 @@ public class BotQuery {
public static void cleanup() {
botInfos.clear();
botKeyboards.clear();
botKeyboardsByMids.clear();
}
public static void clearBotKeyboard(final long did, final ArrayList<Integer> messages) {
@ -68,11 +70,11 @@ public class BotQuery {
NativeByteBuffer data;
if (!cursor.isNull(0)) {
data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
data = cursor.byteBufferValue(0);
if (data != null) {
botKeyboard = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
}
data.reuse();
}
}
cursor.dispose();
@ -111,11 +113,11 @@ public class BotQuery {
NativeByteBuffer data;
if (!cursor.isNull(0)) {
data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
data = cursor.byteBufferValue(0);
if (data != null) {
botInfo = TLRPC.BotInfo.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
}
data.reuse();
}
}
cursor.dispose();

View file

@ -57,24 +57,25 @@ public class MessagesQuery {
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data, mid, date FROM messages WHERE mid = %d", messageId));
if (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
result = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
result.id = cursor.intValue(1);
result.date = cursor.intValue(2);
result.dialog_id = -channelId;
MessagesStorage.addUsersAndChatsFromMessage(result, usersToLoad, chatsToLoad);
}
data.reuse();
}
cursor.dispose();
if (result == null) {
cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data FROM chat_pinned WHERE uid = %d", channelId));
if (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
result = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (result.id != mid) {
result = null;
} else {
@ -82,7 +83,6 @@ public class MessagesQuery {
MessagesStorage.addUsersAndChatsFromMessage(result, usersToLoad, chatsToLoad);
}
}
data.reuse();
}
cursor.dispose();
}
@ -213,14 +213,14 @@ public class MessagesQuery {
try {
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid, m.date, r.random_id FROM randoms as r INNER JOIN messages as m ON r.mid = m.mid WHERE r.random_id IN(%s)", TextUtils.join(",", replyMessages)));
while (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
message.id = cursor.intValue(1);
message.date = cursor.intValue(2);
message.dialog_id = dialogId;
ArrayList<MessageObject> arrayList = replyMessageRandomOwners.remove(cursor.longValue(3));
if (arrayList != null) {
MessageObject messageObject = new MessageObject(message, null, null, false);
@ -231,7 +231,6 @@ public class MessagesQuery {
}
}
}
data.reuse();
}
cursor.dispose();
if (!replyMessageRandomOwners.isEmpty()) {
@ -299,9 +298,10 @@ public class MessagesQuery {
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data, mid, date FROM messages WHERE mid IN(%s)", stringBuilder.toString()));
while (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
message.id = cursor.intValue(1);
message.date = cursor.intValue(2);
message.dialog_id = dialogId;
@ -309,7 +309,6 @@ public class MessagesQuery {
result.add(message);
replyMessages.remove((Integer) message.id);
}
data.reuse();
}
cursor.dispose();

View file

@ -0,0 +1,410 @@
/*
* This is the source code of Telegram for Android v. 3.x.x.
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Nikolai Kudashov, 2013-2016.
*/
package org.telegram.messenger.query;
import android.text.TextUtils;
import org.telegram.SQLite.SQLiteCursor;
import org.telegram.SQLite.SQLitePreparedStatement;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.MessagesStorage;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.UserConfig;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.RequestDelegate;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Locale;
public class SearchQuery {
public static ArrayList<TLRPC.TL_topPeer> hints = new ArrayList<>();
public static ArrayList<TLRPC.TL_topPeer> inlineBots = new ArrayList<>();
private static HashMap<Integer, Integer> inlineDates = new HashMap<>();
private static boolean loaded;
private static boolean loading;
public static void cleanUp() {
loading = false;
loaded = false;
hints.clear();
inlineBots.clear();
inlineDates.clear();
NotificationCenter.getInstance().postNotificationName(NotificationCenter.reloadHints);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.reloadInlineHints);
}
public static void loadHints(boolean cache) {
if (loading) {
return;
}
if (cache) {
if (loaded) {
return;
}
loading = true;
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
final ArrayList<TLRPC.TL_topPeer> hintsNew = new ArrayList<>();
final ArrayList<TLRPC.TL_topPeer> inlineBotsNew = new ArrayList<>();
final HashMap<Integer, Integer> inlineDatesNew = new HashMap<>();
final ArrayList<TLRPC.User> users = new ArrayList<>();
final ArrayList<TLRPC.Chat> chats = new ArrayList<>();
try {
ArrayList<Integer> usersToLoad = new ArrayList<>();
ArrayList<Integer> chatsToLoad = new ArrayList<>();
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT did, type, rating, date FROM chat_hints WHERE 1 ORDER BY rating DESC");
while (cursor.next()) {
int did = cursor.intValue(0);
int type = cursor.intValue(1);
TLRPC.TL_topPeer peer = new TLRPC.TL_topPeer();
peer.rating = cursor.doubleValue(2);
if (did > 0) {
peer.peer = new TLRPC.TL_peerUser();
peer.peer.user_id = did;
usersToLoad.add(did);
} else {
peer.peer = new TLRPC.TL_peerChat();
peer.peer.chat_id = -did;
chatsToLoad.add(-did);
}
if (type == 0) {
hintsNew.add(peer);
} else if (type == 1) {
inlineBotsNew.add(peer);
inlineDatesNew.put(did, cursor.intValue(3));
}
}
cursor.dispose();
if (!usersToLoad.isEmpty()) {
MessagesStorage.getInstance().getUsersInternal(TextUtils.join(",", usersToLoad), users);
}
if (!chatsToLoad.isEmpty()) {
MessagesStorage.getInstance().getChatsInternal(TextUtils.join(",", chatsToLoad), chats);
}
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
MessagesController.getInstance().putUsers(users, true);
MessagesController.getInstance().putChats(chats, true);
loading = false;
loaded = true;
hints = hintsNew;
inlineBots = inlineBotsNew;
inlineDates = inlineDatesNew;
NotificationCenter.getInstance().postNotificationName(NotificationCenter.reloadHints);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.reloadInlineHints);
if (Math.abs(UserConfig.lastHintsSyncTime - (int) (System.currentTimeMillis() / 1000)) >= 24 * 60 * 60) {
loadHints(false);
}
}
});
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
loaded = true;
} else {
loading = true;
TLRPC.TL_contacts_getTopPeers req = new TLRPC.TL_contacts_getTopPeers();
req.hash = 0;
req.bots_pm = false;
req.correspondents = true;
req.groups = false;
req.channels = false;
req.bots_inline = true;
req.offset = 0;
req.limit = 20;
ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
@Override
public void run(final TLObject response, TLRPC.TL_error error) {
if (response instanceof TLRPC.TL_contacts_topPeers) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
final TLRPC.TL_contacts_topPeers topPeers = (TLRPC.TL_contacts_topPeers) response;
MessagesController.getInstance().putUsers(topPeers.users, false);
MessagesController.getInstance().putChats(topPeers.chats, false);
for (int a = 0; a < topPeers.categories.size(); a++) {
TLRPC.TL_topPeerCategoryPeers category = topPeers.categories.get(a);
if (category.category instanceof TLRPC.TL_topPeerCategoryBotsInline) {
inlineBots = category.peers;
} else {
hints = category.peers;
}
}
NotificationCenter.getInstance().postNotificationName(NotificationCenter.reloadHints);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.reloadInlineHints);
final HashMap<Integer, Integer> inlineDatesCopy = new HashMap<>(inlineDates);
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
try {
MessagesStorage.getInstance().getDatabase().executeFast("DELETE FROM chat_hints WHERE 1").stepThis().dispose();
MessagesStorage.getInstance().getDatabase().beginTransaction();
MessagesStorage.getInstance().putUsersAndChats(topPeers.users, topPeers.chats, false, false);
SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO chat_hints VALUES(?, ?, ?, ?)");
for (int a = 0; a < topPeers.categories.size(); a++) {
int type;
TLRPC.TL_topPeerCategoryPeers category = topPeers.categories.get(a);
if (category.category instanceof TLRPC.TL_topPeerCategoryBotsInline) {
type = 1;
} else {
type = 0;
}
for (int b = 0; b < category.peers.size(); b++) {
TLRPC.TL_topPeer peer = category.peers.get(b);
int did;
if (peer.peer instanceof TLRPC.TL_peerUser) {
did = peer.peer.user_id;
} else if (peer.peer instanceof TLRPC.TL_peerChat) {
did = -peer.peer.chat_id;
} else {
did = -peer.peer.channel_id;
}
Integer date = inlineDatesCopy.get(did);
state.requery();
state.bindInteger(1, did);
state.bindInteger(2, type);
state.bindDouble(3, peer.rating);
state.bindInteger(4, date != null ? date : 0);
state.step();
}
}
state.dispose();
MessagesStorage.getInstance().getDatabase().commitTransaction();
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
UserConfig.lastHintsSyncTime = (int) (System.currentTimeMillis() / 1000);
UserConfig.saveConfig(false);
}
});
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
}
});
}
}
});
}
}
public static void increaseInlineRaiting(final int uid) {
Integer time = inlineDates.get(uid);
int dt;
if (time != null) {
dt = Math.max(1, ((int) (System.currentTimeMillis() / 1000)) - time);
} else {
dt = 60;
}
TLRPC.TL_topPeer peer = null;
for (int a = 0; a < inlineBots.size(); a++) {
TLRPC.TL_topPeer p = inlineBots.get(a);
if (p.peer.user_id == uid) {
peer = p;
break;
}
}
if (peer == null) {
peer = new TLRPC.TL_topPeer();
peer.peer = new TLRPC.TL_peerUser();
peer.peer.user_id = uid;
inlineBots.add(peer);
}
peer.rating += Math.exp(dt / MessagesController.getInstance().ratingDecay);
Collections.sort(inlineBots, new Comparator<TLRPC.TL_topPeer>() {
@Override
public int compare(TLRPC.TL_topPeer lhs, TLRPC.TL_topPeer rhs) {
if (lhs.rating > rhs.rating) {
return -1;
} else if (lhs.rating < rhs.rating) {
return 1;
}
return 0;
}
});
if (inlineBots.size() > 20) {
inlineBots.remove(inlineBots.size() - 1);
}
savePeer(uid, 1, peer.rating);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.reloadInlineHints);
}
public static void removeInline(final int uid) {
TLRPC.TL_topPeerCategoryPeers category = null;
for (int a = 0; a < inlineBots.size(); a++) {
if (inlineBots.get(a).peer.user_id == uid) {
inlineBots.remove(a);
TLRPC.TL_contacts_resetTopPeerRating req = new TLRPC.TL_contacts_resetTopPeerRating();
req.category = new TLRPC.TL_topPeerCategoryBotsInline();
req.peer = MessagesController.getInputPeer(uid);
ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
@Override
public void run(TLObject response, TLRPC.TL_error error) {
}
});
deletePeer(uid, 1);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.reloadInlineHints);
return;
}
}
}
public static void removePeer(final int uid) {
TLRPC.TL_topPeerCategoryPeers category = null;
for (int a = 0; a < hints.size(); a++) {
if (hints.get(a).peer.user_id == uid) {
hints.remove(a);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.reloadHints);
TLRPC.TL_contacts_resetTopPeerRating req = new TLRPC.TL_contacts_resetTopPeerRating();
req.category = new TLRPC.TL_topPeerCategoryCorrespondents();
req.peer = MessagesController.getInputPeer(uid);
deletePeer(uid, 0);
ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
@Override
public void run(TLObject response, TLRPC.TL_error error) {
}
});
return;
}
}
}
public static void increasePeerRaiting(final long did) {
final int lower_id = (int) did;
if (lower_id <= 0) {
return;
}
//remove chats and bots for now
final TLRPC.User user = lower_id > 0 ? MessagesController.getInstance().getUser(lower_id) : null;
//final TLRPC.Chat chat = lower_id < 0 ? MessagesController.getInstance().getChat(-lower_id) : null;
if (user == null || user.bot/*&& chat == null || ChatObject.isChannel(chat) && !chat.megagroup*/) {
return;
}
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
double dt = 0;
try {
int lastTime = 0;
int lastMid = 0;
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT MAX(mid), MAX(date) FROM messages WHERE uid = %d AND out = 1", did));
if (cursor.next()) {
lastMid = cursor.intValue(0);
lastTime = cursor.intValue(1);
}
cursor.dispose();
if (lastMid > 0) {
cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT date FROM messages WHERE uid = %d AND mid < %d AND out = 1 ORDER BY date DESC", did, lastMid));
if (cursor.next()) {
dt = (lastTime - cursor.intValue(0));
}
cursor.dispose();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
final double dtFinal = dt;
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
TLRPC.TL_topPeer peer = null;
for (int a = 0; a < hints.size(); a++) {
TLRPC.TL_topPeer p = hints.get(a);
if (lower_id < 0 && (p.peer.chat_id == -lower_id || p.peer.channel_id == -lower_id) || lower_id > 0 && p.peer.user_id == lower_id) {
peer = p;
break;
}
}
if (peer == null) {
peer = new TLRPC.TL_topPeer();
if (lower_id > 0) {
peer.peer = new TLRPC.TL_peerUser();
peer.peer.user_id = lower_id;
} else {
peer.peer = new TLRPC.TL_peerChat();
peer.peer.chat_id = -lower_id;
}
hints.add(peer);
}
peer.rating += Math.exp(dtFinal / MessagesController.getInstance().ratingDecay);
Collections.sort(hints, new Comparator<TLRPC.TL_topPeer>() {
@Override
public int compare(TLRPC.TL_topPeer lhs, TLRPC.TL_topPeer rhs) {
if (lhs.rating > rhs.rating) {
return -1;
} else if (lhs.rating < rhs.rating) {
return 1;
}
return 0;
}
});
savePeer((int) did, 0, peer.rating);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.reloadHints);
}
});
}
});
}
private static void savePeer(final int did, final int type, final double rating) {
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
try {
SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO chat_hints VALUES(?, ?, ?, ?)");
state.requery();
state.bindInteger(1, did);
state.bindInteger(2, type);
state.bindDouble(3, rating);
state.bindInteger(4, (int) System.currentTimeMillis() / 1000);
state.step();
state.dispose();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
}
private static void deletePeer(final int did, final int type) {
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
try {
MessagesStorage.getInstance().getDatabase().executeFast(String.format(Locale.US, "DELETE FROM chat_hints WHERE did = %d AND type = %d", did, type)).stepThis().dispose();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
}
}

View file

@ -375,9 +375,10 @@ public class SharedMediaQuery {
}
while (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
message.id = cursor.intValue(1);
message.dialog_id = uid;
if ((int) uid == 0) {
@ -394,7 +395,6 @@ public class SharedMediaQuery {
}
}
}
data.reuse();
}
cursor.dispose();
@ -481,16 +481,16 @@ public class SharedMediaQuery {
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v2 WHERE uid = %d AND mid < %d AND type = %d ORDER BY date DESC, mid DESC LIMIT 1000", uid, max_id, MEDIA_MUSIC));
while (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (MessageObject.isMusicMessage(message)) {
message.id = cursor.intValue(1);
message.dialog_id = uid;
arrayList.add(0, new MessageObject(message, null, false));
}
}
data.reuse();
}
cursor.dispose();
} catch (Exception e) {

View file

@ -179,18 +179,18 @@ public class StickersQuery {
try {
cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT data, date, hash FROM stickers_v2 WHERE 1");
if (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
newStickerArray = new ArrayList<>();
int count = data.readInt32(false);
for (int a = 0; a < count; a++) {
TLRPC.TL_messages_stickerSet stickerSet = TLRPC.TL_messages_stickerSet.TLdeserialize(data, data.readInt32(false), false);
newStickerArray.add(stickerSet);
}
data.reuse();
}
date = cursor.intValue(1);
hash = calcStickersHash(newStickerArray);
data.reuse();
}
} catch (Throwable e) {
FileLog.e("tmessages", e);

View file

@ -18,7 +18,6 @@
package org.telegram.messenger.support.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.database.Observable;
import android.graphics.Canvas;
import android.graphics.PointF;
@ -59,7 +58,6 @@ import android.view.FocusFinder;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewParent;
@ -153,9 +151,6 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
private static final boolean DEBUG = false;
private static final int[] NESTED_SCROLLING_ATTRS
= {16843830 /* android.R.attr.nestedScrollingEnabled */};
/**
* On Kitkat and JB MR2, there is a bug which prevents DisplayList from being invalidated if
* a View is two levels deep(wrt to ViewHolder.itemView). DisplayList can be invalidated by
@ -859,6 +854,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
*/
public void setAdapter(Adapter adapter) {
// bail out if layout is frozen
stopScroll();
setLayoutFrozen(false);
setAdapterInternal(adapter, false, true);
requestLayout();

View file

@ -133,6 +133,7 @@ public class ConnectionsManager {
TLRPC.TL_error error = null;
if (response != 0) {
NativeByteBuffer buff = NativeByteBuffer.wrap(response);
buff.reused = true;
resp = object.deserializeResponse(buff, buff.readInt32(true), true);
} else if (errorText != null) {
error = new TLRPC.TL_error();
@ -260,6 +261,7 @@ public class ConnectionsManager {
public static void onUnparsedMessageReceived(int address) {
try {
NativeByteBuffer buff = NativeByteBuffer.wrap(address);
buff.reused = true;
final TLObject message = TLClassStore.Instance().TLdeserialize(buff, buff.readInt32(true), true);
if (message instanceof TLRPC.Updates) {
FileLog.d("tmessages", "java received " + message);
@ -327,6 +329,7 @@ public class ConnectionsManager {
public static void onUpdateConfig(int address) {
try {
NativeByteBuffer buff = NativeByteBuffer.wrap(address);
buff.reused = true;
final TLRPC.TL_config message = TLRPC.TL_config.TLdeserialize(buff, buff.readInt32(true), true);
if (message != null) {
Utilities.stageQueue.postRunnable(new Runnable() {

View file

@ -9,8 +9,9 @@ public class NativeByteBuffer extends AbstractSerializedData {
protected int address;
public ByteBuffer buffer;
private boolean justCalc = false;
private int len = 0;
private boolean justCalc;
private int len;
public boolean reused = true;
private static final ThreadLocal<NativeByteBuffer> addressWrapper = new ThreadLocal<NativeByteBuffer>() {
@Override
@ -22,14 +23,16 @@ public class NativeByteBuffer extends AbstractSerializedData {
public static NativeByteBuffer wrap(int address) {
NativeByteBuffer result = addressWrapper.get();
if (address != 0) {
if (!result.reused) {
FileLog.e("tmessages", "forgot to reuse?");
}
result.address = address;
result.reused = false;
result.buffer = native_getJavaByteBuffer(address);
result.buffer.limit(native_limit(address));
int position = native_position(address);
if (position <= result.buffer.limit()) {
result.buffer.position(position);
} else {
FileLog.e("tmessages", "what with position " + position);
}
result.buffer.order(ByteOrder.LITTLE_ENDIAN);
}
@ -494,6 +497,7 @@ public class NativeByteBuffer extends AbstractSerializedData {
public void reuse() {
if (address != 0) {
reused = true;
native_reuse(address);
}
}

View file

@ -54,9 +54,10 @@ public class TLRPC {
public static final int MESSAGE_FLAG_HAS_MEDIA = 0x00000200;
public static final int MESSAGE_FLAG_HAS_VIEWS = 0x00000400;
public static final int MESSAGE_FLAG_HAS_BOT_ID = 0x00000800;
public static final int MESSAGE_FLAG_EDITED = 0x00008000;
public static final int MESSAGE_FLAG_MEGAGROUP = 0x80000000;
public static final int LAYER = 51;
public static final int LAYER = 52;
public static class ChatPhoto extends TLObject {
public FileLocation photo_small;
@ -4422,6 +4423,59 @@ public class TLRPC {
}
}
public static class TL_topPeerCategoryPeers extends TLObject {
public static int constructor = 0xfb834291;
public TopPeerCategory category;
public int count;
public ArrayList<TL_topPeer> peers = new ArrayList<>();
public static TL_topPeerCategoryPeers TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
if (TL_topPeerCategoryPeers.constructor != constructor) {
if (exception) {
throw new RuntimeException(String.format("can't parse magic %x in TL_topPeerCategoryPeers", constructor));
} else {
return null;
}
}
TL_topPeerCategoryPeers result = new TL_topPeerCategoryPeers();
result.readParams(stream, exception);
return result;
}
public void readParams(AbstractSerializedData stream, boolean exception) {
category = TopPeerCategory.TLdeserialize(stream, stream.readInt32(exception), exception);
count = stream.readInt32(exception);
int magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
int count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TL_topPeer object = TL_topPeer.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
peers.add(object);
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
category.serializeToStream(stream);
stream.writeInt32(count);
stream.writeInt32(0x1cb5c415);
int count = peers.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
peers.get(a).serializeToStream(stream);
}
}
}
public static class InputUser extends TLObject {
public int user_id;
public long access_hash;
@ -5213,9 +5267,9 @@ public class TLRPC {
public void readParams(AbstractSerializedData stream, boolean exception) {
email_pattern = stream.readString(exception);
}
}
public void serializeToStream(AbstractSerializedData stream) {
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeString(email_pattern);
}
@ -7246,6 +7300,82 @@ public class TLRPC {
}
}
public static class TopPeerCategory extends TLObject {
public static TopPeerCategory TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
TopPeerCategory result = null;
switch(constructor) {
case 0x637b7ed:
result = new TL_topPeerCategoryCorrespondents();
break;
case 0xbd17a14a:
result = new TL_topPeerCategoryGroups();
break;
case 0x148677e2:
result = new TL_topPeerCategoryBotsInline();
break;
case 0x161d9628:
result = new TL_topPeerCategoryChannels();
break;
case 0xab661b5b:
result = new TL_topPeerCategoryBotsPM();
break;
}
if (result == null && exception) {
throw new RuntimeException(String.format("can't parse magic %x in TopPeerCategory", constructor));
}
if (result != null) {
result.readParams(stream, exception);
}
return result;
}
}
public static class TL_topPeerCategoryCorrespondents extends TopPeerCategory {
public static int constructor = 0x637b7ed;
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
}
}
public static class TL_topPeerCategoryGroups extends TopPeerCategory {
public static int constructor = 0xbd17a14a;
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
}
}
public static class TL_topPeerCategoryBotsInline extends TopPeerCategory {
public static int constructor = 0x148677e2;
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
}
}
public static class TL_topPeerCategoryChannels extends TopPeerCategory {
public static int constructor = 0x161d9628;
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
}
}
public static class TL_topPeerCategoryBotsPM extends TopPeerCategory {
public static int constructor = 0xab661b5b;
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
}
}
public static class TL_contactBlocked extends TLObject {
public static int constructor = 0x561bc879;
@ -10509,21 +10639,18 @@ public class TLRPC {
public static class MessageEntity extends TLObject {
public int offset;
public int length;
public String language;
public int length;
public String url;
public String language;
public static MessageEntity TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
MessageEntity result = null;
MessageEntity result = null;
switch(constructor) {
case 0x6ed02538:
result = new TL_messageEntityUrl();
case 0x76a6d327:
result = new TL_messageEntityTextUrl();
break;
case 0xbd610bc9:
result = new TL_messageEntityBold();
break;
case 0x826f8b60:
result = new TL_messageEntityItalic();
case 0x6cef8ac7:
result = new TL_messageEntityBotCommand();
break;
case 0x64e475c2:
result = new TL_messageEntityEmail();
@ -10531,24 +10658,33 @@ public class TLRPC {
case 0x73924be0:
result = new TL_messageEntityPre();
break;
case 0x76a6d327:
result = new TL_messageEntityTextUrl();
break;
case 0xbb92ba95:
result = new TL_messageEntityUnknown();
break;
case 0x6ed02538:
result = new TL_messageEntityUrl();
break;
case 0x826f8b60:
result = new TL_messageEntityItalic();
break;
case 0xfa04579d:
result = new TL_messageEntityMention();
break;
case 0x352dca58:
result = new TL_messageEntityMentionName();
break;
case 0x208e68c9:
result = new TL_inputMessageEntityMentionName();
break;
case 0xbd610bc9:
result = new TL_messageEntityBold();
break;
case 0x6f635b0d:
result = new TL_messageEntityHashtag();
break;
case 0x6cef8ac7:
result = new TL_messageEntityBotCommand();
break;
case 0x28a20571:
result = new TL_messageEntityCode();
break;
case 0xfa04579d:
result = new TL_messageEntityMention();
break;
}
if (result == null && exception) {
throw new RuntimeException(String.format("can't parse magic %x in MessageEntity", constructor));
@ -10560,8 +10696,26 @@ public class TLRPC {
}
}
public static class TL_messageEntityUrl extends MessageEntity {
public static int constructor = 0x6ed02538;
public static class TL_messageEntityTextUrl extends MessageEntity {
public static int constructor = 0x76a6d327;
public void readParams(AbstractSerializedData stream, boolean exception) {
offset = stream.readInt32(exception);
length = stream.readInt32(exception);
url = stream.readString(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(offset);
stream.writeInt32(length);
stream.writeString(url);
}
}
public static class TL_messageEntityBotCommand extends MessageEntity {
public static int constructor = 0x6cef8ac7;
public void readParams(AbstractSerializedData stream, boolean exception) {
@ -10576,8 +10730,58 @@ public class TLRPC {
}
}
public static class TL_messageEntityBold extends MessageEntity {
public static int constructor = 0xbd610bc9;
public static class TL_messageEntityEmail extends MessageEntity {
public static int constructor = 0x64e475c2;
public void readParams(AbstractSerializedData stream, boolean exception) {
offset = stream.readInt32(exception);
length = stream.readInt32(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(offset);
stream.writeInt32(length);
}
}
public static class TL_messageEntityPre extends MessageEntity {
public static int constructor = 0x73924be0;
public void readParams(AbstractSerializedData stream, boolean exception) {
offset = stream.readInt32(exception);
length = stream.readInt32(exception);
language = stream.readString(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(offset);
stream.writeInt32(length);
stream.writeString(language);
}
}
public static class TL_messageEntityUnknown extends MessageEntity {
public static int constructor = 0xbb92ba95;
public void readParams(AbstractSerializedData stream, boolean exception) {
offset = stream.readInt32(exception);
length = stream.readInt32(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(offset);
stream.writeInt32(length);
}
}
public static class TL_messageEntityUrl extends MessageEntity {
public static int constructor = 0x6ed02538;
public void readParams(AbstractSerializedData stream, boolean exception) {
@ -10608,68 +10812,70 @@ public class TLRPC {
}
}
public static class TL_messageEntityEmail extends MessageEntity {
public static int constructor = 0x64e475c2;
public void readParams(AbstractSerializedData stream, boolean exception) {
offset = stream.readInt32(exception);
length = stream.readInt32(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(offset);
stream.writeInt32(length);
}
}
public static class TL_messageEntityPre extends MessageEntity {
public static int constructor = 0x73924be0;
public void readParams(AbstractSerializedData stream, boolean exception) {
offset = stream.readInt32(exception);
length = stream.readInt32(exception);
language = stream.readString(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(offset);
stream.writeInt32(length);
stream.writeString(language);
}
}
public static class TL_messageEntityTextUrl extends MessageEntity {
public static int constructor = 0x76a6d327;
public static class TL_messageEntityMention extends MessageEntity {
public static int constructor = 0xfa04579d;
public void readParams(AbstractSerializedData stream, boolean exception) {
offset = stream.readInt32(exception);
length = stream.readInt32(exception);
url = stream.readString(exception);
length = stream.readInt32(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(offset);
stream.writeInt32(length);
stream.writeString(url);
}
}
public static class TL_messageEntityUnknown extends MessageEntity {
public static int constructor = 0xbb92ba95;
public static class TL_messageEntityMentionName extends MessageEntity {
public static int constructor = 0x352dca58;
public int user_id;
public void readParams(AbstractSerializedData stream, boolean exception) {
offset = stream.readInt32(exception);
length = stream.readInt32(exception);
user_id = stream.readInt32(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(offset);
stream.writeInt32(length);
stream.writeInt32(user_id);
}
}
public static class TL_inputMessageEntityMentionName extends MessageEntity {
public static int constructor = 0x208e68c9;
public InputUser user_id;
public void readParams(AbstractSerializedData stream, boolean exception) {
offset = stream.readInt32(exception);
length = stream.readInt32(exception);
user_id = InputUser.TLdeserialize(stream, stream.readInt32(exception), exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(offset);
stream.writeInt32(length);
user_id.serializeToStream(stream);
}
}
public static class TL_messageEntityBold extends MessageEntity {
public static int constructor = 0xbd610bc9;
public void readParams(AbstractSerializedData stream, boolean exception) {
offset = stream.readInt32(exception);
offset = stream.readInt32(exception);
length = stream.readInt32(exception);
}
}
public void serializeToStream(AbstractSerializedData stream) {
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(offset);
stream.writeInt32(length);
@ -10692,42 +10898,10 @@ public class TLRPC {
}
}
public static class TL_messageEntityBotCommand extends MessageEntity {
public static int constructor = 0x6cef8ac7;
public void readParams(AbstractSerializedData stream, boolean exception) {
offset = stream.readInt32(exception);
length = stream.readInt32(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(offset);
stream.writeInt32(length);
}
}
public static class TL_messageEntityCode extends MessageEntity {
public static int constructor = 0x28a20571;
public void readParams(AbstractSerializedData stream, boolean exception) {
offset = stream.readInt32(exception);
length = stream.readInt32(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(offset);
stream.writeInt32(length);
}
}
public static class TL_messageEntityMention extends MessageEntity {
public static int constructor = 0xfa04579d;
public void readParams(AbstractSerializedData stream, boolean exception) {
offset = stream.readInt32(exception);
length = stream.readInt32(exception);
@ -11177,7 +11351,7 @@ public class TLRPC {
}
public static class TL_config extends TLObject {
public static int constructor = 0x317ceef4;
public static int constructor = 0xc9411388;
public int date;
public int expires;
@ -11198,6 +11372,7 @@ public class TLRPC {
public int push_chat_limit;
public int saved_gifs_limit;
public int edit_time_limit;
public int rating_e_decay;
public ArrayList<TL_disabledFeature> disabled_features = new ArrayList<>();
public static TL_config TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
@ -11247,6 +11422,7 @@ public class TLRPC {
push_chat_limit = stream.readInt32(exception);
saved_gifs_limit = stream.readInt32(exception);
edit_time_limit = stream.readInt32(exception);
rating_e_decay = stream.readInt32(exception);
magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
@ -11290,6 +11466,7 @@ public class TLRPC {
stream.writeInt32(push_chat_limit);
stream.writeInt32(saved_gifs_limit);
stream.writeInt32(edit_time_limit);
stream.writeInt32(rating_e_decay);
stream.writeInt32(0x1cb5c415);
count = disabled_features.size();
stream.writeInt32(count);
@ -11299,6 +11476,115 @@ public class TLRPC {
}
}
public static class contacts_TopPeers extends TLObject {
public ArrayList<TL_topPeerCategoryPeers> categories = new ArrayList<>();
public ArrayList<Chat> chats = new ArrayList<>();
public ArrayList<User> users = new ArrayList<>();
public static contacts_TopPeers TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
contacts_TopPeers result = null;
switch(constructor) {
case 0x70b772a8:
result = new TL_contacts_topPeers();
break;
case 0xde266ef5:
result = new TL_contacts_topPeersNotModified();
break;
}
if (result == null && exception) {
throw new RuntimeException(String.format("can't parse magic %x in contacts_TopPeers", constructor));
}
if (result != null) {
result.readParams(stream, exception);
}
return result;
}
}
public static class TL_contacts_topPeers extends contacts_TopPeers {
public static int constructor = 0x70b772a8;
public void readParams(AbstractSerializedData stream, boolean exception) {
int magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
int count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TL_topPeerCategoryPeers object = TL_topPeerCategoryPeers.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
categories.add(object);
}
magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
Chat object = Chat.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
chats.add(object);
}
magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
User object = User.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
users.add(object);
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(0x1cb5c415);
int count = categories.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
categories.get(a).serializeToStream(stream);
}
stream.writeInt32(0x1cb5c415);
count = chats.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
chats.get(a).serializeToStream(stream);
}
stream.writeInt32(0x1cb5c415);
count = users.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
users.get(a).serializeToStream(stream);
}
}
}
public static class TL_contacts_topPeersNotModified extends contacts_TopPeers {
public static int constructor = 0xde266ef5;
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
}
}
public static class TL_help_support extends TLObject {
public static int constructor = 0x17c6b5f6;
@ -15671,6 +15957,153 @@ public class TLRPC {
}
}
public static class TL_messages_peerDialogs extends TLObject {
public static int constructor = 0x3371c354;
public ArrayList<Dialog> dialogs = new ArrayList<>();
public ArrayList<Message> messages = new ArrayList<>();
public ArrayList<Chat> chats = new ArrayList<>();
public ArrayList<User> users = new ArrayList<>();
public TL_updates_state state;
public static TL_messages_peerDialogs TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
if (TL_messages_peerDialogs.constructor != constructor) {
if (exception) {
throw new RuntimeException(String.format("can't parse magic %x in TL_messages_peerDialogs", constructor));
} else {
return null;
}
}
TL_messages_peerDialogs result = new TL_messages_peerDialogs();
result.readParams(stream, exception);
return result;
}
public void readParams(AbstractSerializedData stream, boolean exception) {
int magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
int count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
Dialog object = Dialog.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
dialogs.add(object);
}
magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
Message object = Message.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
messages.add(object);
}
magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
Chat object = Chat.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
chats.add(object);
}
magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
User object = User.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
users.add(object);
}
state = TL_updates_state.TLdeserialize(stream, stream.readInt32(exception), exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(0x1cb5c415);
int count = dialogs.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
dialogs.get(a).serializeToStream(stream);
}
stream.writeInt32(0x1cb5c415);
count = messages.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
messages.get(a).serializeToStream(stream);
}
stream.writeInt32(0x1cb5c415);
count = chats.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
chats.get(a).serializeToStream(stream);
}
stream.writeInt32(0x1cb5c415);
count = users.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
users.get(a).serializeToStream(stream);
}
state.serializeToStream(stream);
}
}
public static class TL_topPeer extends TLObject {
public static int constructor = 0xedcdc05b;
public Peer peer;
public double rating;
public static TL_topPeer TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
if (TL_topPeer.constructor != constructor) {
if (exception) {
throw new RuntimeException(String.format("can't parse magic %x in TL_topPeer", constructor));
} else {
return null;
}
}
TL_topPeer result = new TL_topPeer();
result.readParams(stream, exception);
return result;
}
public void readParams(AbstractSerializedData stream, boolean exception) {
peer = Peer.TLdeserialize(stream, stream.readInt32(exception), exception);
rating = stream.readDouble(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
peer.serializeToStream(stream);
stream.writeDouble(rating);
}
}
public static class InputPhotoCrop extends TLObject {
public double crop_left;
public double crop_top;
@ -17948,6 +18381,54 @@ public class TLRPC {
}
}
public static class TL_contacts_getTopPeers extends TLObject {
public static int constructor = 0xd4982db5;
public int flags;
public boolean correspondents;
public boolean bots_pm;
public boolean bots_inline;
public boolean groups;
public boolean channels;
public int offset;
public int limit;
public int hash;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return contacts_TopPeers.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(flags);
flags = correspondents ? (flags | 1) : (flags &~ 1);
flags = bots_pm ? (flags | 2) : (flags &~ 2);
flags = bots_inline ? (flags | 4) : (flags &~ 4);
flags = groups ? (flags | 1024) : (flags &~ 1024);
flags = channels ? (flags | 32768) : (flags &~ 32768);
stream.writeInt32(offset);
stream.writeInt32(limit);
stream.writeInt32(hash);
}
}
public static class TL_contacts_resetTopPeerRating extends TLObject {
public static int constructor = 0x1ae373ac;
public TopPeerCategory category;
public InputPeer peer;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return Bool.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
category.serializeToStream(stream);
peer.serializeToStream(stream);
}
}
public static class TL_account_sendChangePhoneCode extends TLObject {
public static int constructor = 0x8e57deb;
@ -18550,6 +19031,26 @@ public class TLRPC {
}
}
public static class TL_messages_getPeerDialogs extends TLObject {
public static int constructor = 0x2d9776b9;
public ArrayList<InputPeer> peers = new ArrayList<>();
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return TL_messages_peerDialogs.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(0x1cb5c415);
int count = peers.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
peers.get(a).serializeToStream(stream);
}
}
}
public static class TL_messages_editInlineBotMessage extends TLObject {
public static int constructor = 0x130c2c85;

View file

@ -50,6 +50,7 @@ public class ActionBar extends FrameLayout {
private boolean addToContainer = true;
private boolean interceptTouches = true;
private int extraHeight;
private AnimatorSetProxy actionModeAnimation;
private boolean allowOverlayTitle;
private CharSequence lastTitle;
@ -227,10 +228,13 @@ public class ActionBar extends FrameLayout {
if (occupyStatusBar && actionModeTop != null) {
animators.add(ObjectAnimatorProxy.ofFloat(actionModeTop, "alpha", 0.0f, 1.0f));
}
AnimatorSetProxy animatorSetProxy = new AnimatorSetProxy();
animatorSetProxy.playTogether(animators);
animatorSetProxy.setDuration(200);
animatorSetProxy.addListener(new AnimatorListenerAdapterProxy() {
if (actionModeAnimation != null) {
actionModeAnimation.cancel();
}
actionModeAnimation = new AnimatorSetProxy();
actionModeAnimation.playTogether(animators);
actionModeAnimation.setDuration(200);
actionModeAnimation.addListener(new AnimatorListenerAdapterProxy() {
@Override
public void onAnimationStart(Object animation) {
actionMode.setVisibility(VISIBLE);
@ -241,18 +245,28 @@ public class ActionBar extends FrameLayout {
@Override
public void onAnimationEnd(Object animation) {
if (titleTextView != null) {
titleTextView.setVisibility(INVISIBLE);
if (actionModeAnimation != null && actionModeAnimation.equals(animation)) {
actionModeAnimation = null;
if (titleTextView != null) {
titleTextView.setVisibility(INVISIBLE);
}
if (subtitleTextView != null) {
subtitleTextView.setVisibility(INVISIBLE);
}
if (menu != null) {
menu.setVisibility(INVISIBLE);
}
}
if (subtitleTextView != null) {
subtitleTextView.setVisibility(INVISIBLE);
}
if (menu != null) {
menu.setVisibility(INVISIBLE);
}
@Override
public void onAnimationCancel(Object animation) {
if (actionModeAnimation != null && actionModeAnimation.equals(animation)) {
actionModeAnimation = null;
}
}
});
animatorSetProxy.start();
actionModeAnimation.start();
} else {
actionMode.setVisibility(VISIBLE);
if (occupyStatusBar && actionModeTop != null) {
@ -273,7 +287,7 @@ public class ActionBar extends FrameLayout {
if (drawable instanceof BackDrawable) {
((BackDrawable) drawable).setRotation(1, true);
}
backButtonImageView.setBackgroundDrawable(Theme.createBarSelectorDrawable(itemsBackgroundColor));
backButtonImageView.setBackgroundDrawable(Theme.createBarSelectorDrawable(Theme.ACTION_BAR_MODE_SELECTOR_COLOR));
}
}
@ -288,19 +302,32 @@ public class ActionBar extends FrameLayout {
if (occupyStatusBar && actionModeTop != null) {
animators.add(ObjectAnimatorProxy.ofFloat(actionModeTop, "alpha", 0.0f));
}
AnimatorSetProxy animatorSetProxy = new AnimatorSetProxy();
animatorSetProxy.playTogether(animators);
animatorSetProxy.setDuration(200);
animatorSetProxy.addListener(new AnimatorListenerAdapterProxy() {
if (actionModeAnimation != null) {
actionModeAnimation.cancel();
}
actionModeAnimation = new AnimatorSetProxy();
actionModeAnimation.playTogether(animators);
actionModeAnimation.setDuration(200);
actionModeAnimation.addListener(new AnimatorListenerAdapterProxy() {
@Override
public void onAnimationEnd(Object animation) {
actionMode.setVisibility(INVISIBLE);
if (occupyStatusBar && actionModeTop != null) {
actionModeTop.setVisibility(INVISIBLE);
if (actionModeAnimation != null && actionModeAnimation.equals(animation)) {
actionModeAnimation = null;
actionMode.setVisibility(INVISIBLE);
if (occupyStatusBar && actionModeTop != null) {
actionModeTop.setVisibility(INVISIBLE);
}
}
}
@Override
public void onAnimationCancel(Object animation) {
if (actionModeAnimation != null && actionModeAnimation.equals(animation)) {
actionModeAnimation = null;
}
}
});
animatorSetProxy.start();
actionModeAnimation.start();
} else {
actionMode.setVisibility(INVISIBLE);
if (occupyStatusBar && actionModeTop != null) {

View file

@ -29,8 +29,6 @@ import android.widget.FrameLayout;
import android.widget.LinearLayout;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.messenger.AnimationCompat.AnimatorListenerAdapterProxy;
import org.telegram.messenger.AnimationCompat.AnimatorSetProxy;
@ -101,9 +99,6 @@ public class ActionBarLayout extends FrameLayout {
getWindowVisibleDisplayFrame(rect);
int usableViewHeight = rootView.getHeight() - (rect.top != 0 ? AndroidUtilities.statusBarHeight : 0) - AndroidUtilities.getViewInset(rootView);
isKeyboardVisible = usableViewHeight - (rect.bottom - rect.top) > 0;
if (BuildVars.DEBUG_VERSION) {
FileLog.e("tmessages", "keyboard visible = " + isKeyboardVisible + " for " + this);
}
if (waitingForKeyboardCloseRunnable != null && !containerView.isKeyboardVisible && !containerViewBack.isKeyboardVisible) {
AndroidUtilities.cancelRunOnUIThread(waitingForKeyboardCloseRunnable);
waitingForKeyboardCloseRunnable.run();
@ -117,6 +112,7 @@ public class ActionBarLayout extends FrameLayout {
private static Paint scrimPaint;
private Runnable waitingForKeyboardCloseRunnable;
private Runnable delayedOpenAnimationRunnable;
private LinearLayoutContainer containerView;
private LinearLayoutContainer containerViewBack;
@ -629,6 +625,15 @@ public class ActionBarLayout extends FrameLayout {
});
}
public void resumeDelayedFragmentAnimation() {
if (delayedOpenAnimationRunnable == null) {
return;
}
AndroidUtilities.cancelRunOnUIThread(delayedOpenAnimationRunnable);
delayedOpenAnimationRunnable.run();
delayedOpenAnimationRunnable = null;
}
public boolean presentFragment(final BaseFragment fragment, final boolean removeLast, boolean forceWithoutAnimation, boolean check) {
if (checkTransitionAnimation() || delegate != null && check && !delegate.needPresentFragment(fragment, removeLast, forceWithoutAnimation, this) || !fragment.onFragmentCreate()) {
return false;
@ -736,7 +741,6 @@ public class ActionBarLayout extends FrameLayout {
ViewProxy.setTranslationX(containerView, 0);
}
};
FileLog.e("tmessages", "onOpenAnimationsStart");
fragment.onTransitionAnimationStart(true, false);
AnimatorSetProxy animation = fragment.onCustomTransitionAnimation(true, new Runnable() {
@Override
@ -751,7 +755,6 @@ public class ActionBarLayout extends FrameLayout {
waitingForKeyboardCloseRunnable = new Runnable() {
@Override
public void run() {
FileLog.e("tmessages", "start delayed by keyboard open animation");
if (waitingForKeyboardCloseRunnable != this) {
return;
}
@ -759,6 +762,18 @@ public class ActionBarLayout extends FrameLayout {
}
};
AndroidUtilities.runOnUIThread(waitingForKeyboardCloseRunnable, 200);
} else if (fragment.needDelayOpenAnimation()) {
delayedOpenAnimationRunnable = new Runnable() {
@Override
public void run() {
if (delayedOpenAnimationRunnable != this) {
return;
}
delayedOpenAnimationRunnable = null;
startLayoutAnimation(true, true);
}
};
AndroidUtilities.runOnUIThread(delayedOpenAnimationRunnable, 200);
} else {
startLayoutAnimation(true, true);
}
@ -873,7 +888,6 @@ public class ActionBarLayout extends FrameLayout {
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
fragmentView.setLayoutParams(layoutParams);
FileLog.e("tmessages", "onCloseAnimationStart");
previousFragment.onTransitionAnimationStart(true, true);
currentFragment.onTransitionAnimationStart(false, false);
previousFragment.onResume();
@ -918,7 +932,6 @@ public class ActionBarLayout extends FrameLayout {
if (waitingForKeyboardCloseRunnable != this) {
return;
}
FileLog.e("tmessages", "start delayed by keyboard close animation");
startLayoutAnimation(false, true);
}
};
@ -978,7 +991,6 @@ public class ActionBarLayout extends FrameLayout {
onAnimationEndCheck(false);
}
});
FileLog.e("tmessages", "onCloseAnimationsStart");
currentAnimation.start();
} else {
removeFragmentFromStackInternal(currentFragment);
@ -1104,13 +1116,11 @@ public class ActionBarLayout extends FrameLayout {
if (post) {
new Handler().post(new Runnable() {
public void run() {
FileLog.e("tmessages", "onCloseAnimationEnd");
onCloseAnimationEndRunnable.run();
onCloseAnimationEndRunnable = null;
}
});
} else {
FileLog.e("tmessages", "onCloseAnimationEnd");
onCloseAnimationEndRunnable.run();
onCloseAnimationEndRunnable = null;
}
@ -1124,13 +1134,11 @@ public class ActionBarLayout extends FrameLayout {
if (post) {
new Handler().post(new Runnable() {
public void run() {
FileLog.e("tmessages", "onOpenAnimationEnd");
onOpenAnimationEndRunnable.run();
onOpenAnimationEndRunnable = null;
}
});
} else {
FileLog.e("tmessages", "onOpenAnimationEnd");
onOpenAnimationEndRunnable.run();
onOpenAnimationEndRunnable = null;
}

View file

@ -368,6 +368,10 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
iconView.setImageResource(resId);
}
public ImageView getImageView() {
return iconView;
}
public EditText getSearchField() {
return searchField;
}

View file

@ -158,6 +158,10 @@ public class BaseFragment {
}
}
public boolean needDelayOpenAnimation() {
return false;
}
public void onResume() {
}

View file

@ -365,7 +365,6 @@ public class DrawerLayoutContainer extends FrameLayout {
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
inLayout = true;
FileLog.w("tmessages", "onLayout");
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);

View file

@ -123,7 +123,7 @@ public class SimpleTextView extends View implements Drawable.Callback {
} else if (layout.getLineLeft(0) == 0) {
offsetX = width - textWidth;
} else {
offsetX = 0;
offsetX = -AndroidUtilities.dp(8);
}
}
} catch (Exception e) {
@ -134,6 +134,7 @@ public class SimpleTextView extends View implements Drawable.Callback {
textWidth = 0;
textHeight = 0;
}
invalidate();
}
@Override
@ -153,9 +154,7 @@ public class SimpleTextView extends View implements Drawable.Callback {
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
if (changed) {
wasLayout = true;
}
wasLayout = true;
}
public int getTextWidth() {
@ -229,7 +228,6 @@ public class SimpleTextView extends View implements Drawable.Callback {
private void recreateLayoutMaybe() {
if (wasLayout) {
createLayout(getMeasuredWidth());
invalidate();
} else {
requestLayout();
}
@ -276,6 +274,15 @@ public class SimpleTextView extends View implements Drawable.Callback {
@Override
public void invalidateDrawable(Drawable who) {
invalidate();
if (who == leftDrawable) {
invalidate(leftDrawable.getBounds());
} else if (who == rightDrawable) {
invalidate(rightDrawable.getBounds());
}
}
@Override
public boolean hasOverlappingRendering() {
return false;
}
}

View file

@ -55,7 +55,12 @@ public class Theme {
public static final int ACTION_BAR_VIOLET_SELECTOR_COLOR = 0xff735fbe;
public static final int ACTION_BAR_YELLOW_SELECTOR_COLOR = 0xffef9f09;
public static final int ATTACH_SHEET_TEXT_COLOR = 0xff757575;
public static final int DIALOGS_MESSAGE_TEXT_COLOR = 0xff8f8f8f;
public static final int DIALOGS_NAME_TEXT_COLOR = 0xff4d83b3;
public static final int DIALOGS_ATTACH_TEXT_COLOR = 0xff4d83b3;
public static final int DIALOGS_PRINTING_TEXT_COLOR = 0xff4d83b3;
public static final int CHAT_UNREAD_TEXT_COLOR = 0xff5695cc;
public static final int CHAT_ADD_CONTACT_TEXT_COLOR = 0xff4a82b5;
@ -95,6 +100,7 @@ public class Theme {
public static final int SECRET_CHAT_INFO_TEXT_COLOR = 0xffffffff;
public static final int MSG_SELECTED_BACKGROUND_COLOR = 0x6633b5e5;
public static final int MSG_WEB_PREVIEW_DURATION_TEXT_COLOR = 0xffffffff;
public static final int MSG_SECRET_TIME_TEXT_COLOR = 0xffe4e2e0;
public static final int MSG_STICKER_NAME_TEXT_COLOR = 0xffffffff;
@ -331,15 +337,6 @@ public class Theme {
geoInDrawable = context.getResources().getDrawable(R.drawable.location_b);
geoOutDrawable = context.getResources().getDrawable(R.drawable.location_g);
attachButtonDrawables[0] = context.getResources().getDrawable(R.drawable.attach_camera_states);
attachButtonDrawables[1] = context.getResources().getDrawable(R.drawable.attach_gallery_states);
attachButtonDrawables[2] = context.getResources().getDrawable(R.drawable.attach_video_states);
attachButtonDrawables[3] = context.getResources().getDrawable(R.drawable.attach_audio_states);
attachButtonDrawables[4] = context.getResources().getDrawable(R.drawable.attach_file_states);
attachButtonDrawables[5] = context.getResources().getDrawable(R.drawable.attach_contact_states);
attachButtonDrawables[6] = context.getResources().getDrawable(R.drawable.attach_location_states);
attachButtonDrawables[7] = context.getResources().getDrawable(R.drawable.attach_hide_states);
cornerOuter[0] = context.getResources().getDrawable(R.drawable.corner_out_tl);
cornerOuter[1] = context.getResources().getDrawable(R.drawable.corner_out_tr);
cornerOuter[2] = context.getResources().getDrawable(R.drawable.corner_out_br);
@ -368,6 +365,19 @@ public class Theme {
}
}
public static void loadChatResources(Context context) {
if (attachButtonDrawables[0] == null) {
attachButtonDrawables[0] = context.getResources().getDrawable(R.drawable.attach_camera_states);
attachButtonDrawables[1] = context.getResources().getDrawable(R.drawable.attach_gallery_states);
attachButtonDrawables[2] = context.getResources().getDrawable(R.drawable.attach_video_states);
attachButtonDrawables[3] = context.getResources().getDrawable(R.drawable.attach_audio_states);
attachButtonDrawables[4] = context.getResources().getDrawable(R.drawable.attach_file_states);
attachButtonDrawables[5] = context.getResources().getDrawable(R.drawable.attach_contact_states);
attachButtonDrawables[6] = context.getResources().getDrawable(R.drawable.attach_location_states);
attachButtonDrawables[7] = context.getResources().getDrawable(R.drawable.attach_hide_states);
}
}
public static Drawable createBarSelectorDrawable(int color) {
return createBarSelectorDrawable(color, true);
}

View file

@ -127,7 +127,7 @@ public abstract class BaseSearchAdapterRecycler extends RecyclerView.Adapter {
});
}
public void addHashtagsFromMessage(String message) {
public void addHashtagsFromMessage(CharSequence message) {
if (message == null) {
return;
}
@ -140,7 +140,7 @@ public abstract class BaseSearchAdapterRecycler extends RecyclerView.Adapter {
if (message.charAt(start) != '@' && message.charAt(start) != '#') {
start++;
}
String hashtag = message.substring(start, end);
String hashtag = message.subSequence(start, end).toString();
if (hashtagsByText == null) {
hashtagsByText = new HashMap<>();
hashtags = new ArrayList<>();

View file

@ -1,396 +0,0 @@
/*
* This is the source code of Telegram for Android v. 3.x.x
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Nikolai Kudashov, 2013-2016.
*/
package org.telegram.ui.Adapters;
public class ChatActivityAdapter {
/*private Context mContext;
public ChatAdapter(Context context) {
mContext = context;
}
@Override
public boolean areAllItemsEnabled() {
return true;
}
@Override
public boolean isEnabled(int i) {
return true;
}
@Override
public int getCount() {
int count = messages.size();
if (count != 0) {
if (!endReached) {
count++;
}
if (!forward_end_reached) {
count++;
}
}
return count;
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
int offset = 1;
if ((!endReached || !forward_end_reached) && messages.size() != 0) {
if (!endReached) {
offset = 0;
}
if (i == 0 && !endReached || !forward_end_reached && i == (messages.size() + 1 - offset)) {
View progressBar = null;
if (view == null) {
LayoutInflater li = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = li.inflate(R.layout.chat_loading_layout, viewGroup, false);
progressBar = view.findViewById(R.id.progressLayout);
if (ApplicationLoader.isCustomTheme()) {
progressBar.setBackgroundResource(R.drawable.system_loader2);
} else {
progressBar.setBackgroundResource(R.drawable.system_loader1);
}
} else {
progressBar = view.findViewById(R.id.progressLayout);
}
progressBar.setVisibility(loadsCount > 1 ? View.VISIBLE : View.INVISIBLE);
return view;
}
}
final MessageObject message = messages.get(messages.size() - i - offset);
int type = message.contentType;
if (view == null) {
if (type == 0) {
view = new ChatMessageCell(mContext);
}
if (type == 1) {
view = new ChatMediaCell(mContext);
} else if (type == 2) {
view = new ChatAudioCell(mContext);
} else if (type == 3) {
view = new ChatContactCell(mContext);
} else if (type == 6) {
LayoutInflater li = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = li.inflate(R.layout.chat_unread_layout, viewGroup, false);
} else if (type == 4) {
view = new ChatActionCell(mContext);
}
if (view instanceof ChatBaseCell) {
((ChatBaseCell) view).setDelegate(new ChatBaseCell.ChatBaseCellDelegate() {
@Override
public void didPressedUserAvatar(ChatBaseCell cell, TLRPC.User user) {
if (actionBar.isActionModeShowed()) {
processRowSelect(cell);
return;
}
if (user != null && user.id != UserConfig.getClientUserId()) {
Bundle args = new Bundle();
args.putInt("user_id", user.id);
presentFragment(new ProfileActivity(args));
}
}
@Override
public void didPressedCancelSendButton(ChatBaseCell cell) {
MessageObject message = cell.getMessageObject();
if (message.messageOwner.send_state != 0) {
SendMessagesHelper.getInstance().cancelSendingMessage(message);
}
}
@Override
public void didLongPressed(ChatBaseCell cell) {
createMenu(cell, false);
}
@Override
public boolean canPerformActions() {
return actionBar != null && !actionBar.isActionModeShowed();
}
@Override
public void didPressUrl(String url) {
if (url.startsWith("@")) {
openProfileWithUsername(url.substring(1));
} else if (url.startsWith("#")) {
MessagesActivity fragment = new MessagesActivity(null);
fragment.setSearchString(url);
presentFragment(fragment);
}
}
@Override
public void didPressReplyMessage(ChatBaseCell cell, int id) {
scrollToMessageId(id, cell.getMessageObject().getId(), true);
}
});
if (view instanceof ChatMediaCell) {
((ChatMediaCell) view).setAllowedToSetPhoto(openAnimationEnded);
((ChatMediaCell) view).setMediaDelegate(new ChatMediaCell.ChatMediaCellDelegate() {
@Override
public void didClickedImage(ChatMediaCell cell) {
MessageObject message = cell.getMessageObject();
if (message.isSendError()) {
createMenu(cell, false);
return;
} else if (message.isSending()) {
return;
}
if (message.type == 1) {
PhotoViewer.getInstance().setParentActivity(getParentActivity());
PhotoViewer.getInstance().openPhoto(message, ChatActivity.this);
} else if (message.type == 3) {
sendSecretMessageRead(message);
try {
File f = null;
if (message.messageOwner.attachPath != null && message.messageOwner.attachPath.length() != 0) {
f = new File(message.messageOwner.attachPath);
}
if (f == null || f != null && !f.exists()) {
f = FileLoader.getPathToMessage(message.messageOwner);
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(f), "video/mp4");
getParentActivity().startActivityForResult(intent, 500);
} catch (Exception e) {
alertUserOpenError(message);
}
} else if (message.type == 4) {
if (!isGoogleMapsInstalled()) {
return;
}
LocationActivity fragment = new LocationActivity();
fragment.setMessageObject(message);
presentFragment(fragment);
} else if (message.type == 9) {
File f = null;
String fileName = message.getFileName();
if (message.messageOwner.attachPath != null && message.messageOwner.attachPath.length() != 0) {
f = new File(message.messageOwner.attachPath);
}
if (f == null || f != null && !f.exists()) {
f = FileLoader.getPathToMessage(message.messageOwner);
}
if (f != null && f.exists()) {
String realMimeType = null;
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
if (message.type == 8 || message.type == 9) {
MimeTypeMap myMime = MimeTypeMap.getSingleton();
int idx = fileName.lastIndexOf('.');
if (idx != -1) {
String ext = fileName.substring(idx + 1);
realMimeType = myMime.getMimeTypeFromExtension(ext.toLowerCase());
if (realMimeType == null) {
realMimeType = message.messageOwner.media.document.mime_type;
if (realMimeType == null || realMimeType.length() == 0) {
realMimeType = null;
}
}
if (realMimeType != null) {
intent.setDataAndType(Uri.fromFile(f), realMimeType);
} else {
intent.setDataAndType(Uri.fromFile(f), "text/plain");
}
} else {
intent.setDataAndType(Uri.fromFile(f), "text/plain");
}
}
if (realMimeType != null) {
try {
getParentActivity().startActivityForResult(intent, 500);
} catch (Exception e) {
intent.setDataAndType(Uri.fromFile(f), "text/plain");
getParentActivity().startActivityForResult(intent, 500);
}
} else {
getParentActivity().startActivityForResult(intent, 500);
}
} catch (Exception e) {
alertUserOpenError(message);
}
}
}
}
@Override
public void didPressedOther(ChatMediaCell cell) {
createMenu(cell, true);
}
});
} else if (view instanceof ChatContactCell) {
((ChatContactCell) view).setContactDelegate(new ChatContactCell.ChatContactCellDelegate() {
@Override
public void didClickAddButton(ChatContactCell cell, TLRPC.User user) {
if (actionBar.isActionModeShowed()) {
processRowSelect(cell);
return;
}
MessageObject messageObject = cell.getMessageObject();
Bundle args = new Bundle();
args.putInt("user_id", messageObject.messageOwner.media.user_id);
args.putString("phone", messageObject.messageOwner.media.phone_number);
args.putBoolean("addContact", true);
presentFragment(new ContactAddActivity(args));
}
@Override
public void didClickPhone(ChatContactCell cell) {
if (actionBar.isActionModeShowed()) {
processRowSelect(cell);
return;
}
final MessageObject messageObject = cell.getMessageObject();
if (getParentActivity() == null || messageObject.messageOwner.media.phone_number == null || messageObject.messageOwner.media.phone_number.length() == 0) {
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
builder.setItems(new CharSequence[]{LocaleController.getString("Copy", R.string.Copy), LocaleController.getString("Call", R.string.Call)}, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
if (i == 1) {
try {
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + messageObject.messageOwner.media.phone_number));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getParentActivity().startActivityForResult(intent, 500);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
} else if (i == 0) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
android.text.ClipboardManager clipboard = (android.text.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE);
clipboard.setText(messageObject.messageOwner.media.phone_number);
} else {
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE);
android.content.ClipData clip = android.content.ClipData.newPlainText("label", messageObject.messageOwner.media.phone_number);
clipboard.setPrimaryClip(clip);
}
}
}
}
);
showDialog(builder.create());
}
});
}
} else if (view instanceof ChatActionCell) {
((ChatActionCell) view).setDelegate(new ChatActionCell.ChatActionCellDelegate() {
@Override
public void didClickedImage(ChatActionCell cell) {
MessageObject message = cell.getMessageObject();
PhotoViewer.getInstance().setParentActivity(getParentActivity());
PhotoViewer.getInstance().openPhoto(message, ChatActivity.this);
}
@Override
public void didLongPressed(ChatActionCell cell) {
createMenu(cell, false);
}
@Override
public void needOpenUserProfile(int uid) {
if (uid != UserConfig.getClientUserId()) {
Bundle args = new Bundle();
args.putInt("user_id", uid);
presentFragment(new ProfileActivity(args));
}
}
});
}
}
boolean selected = false;
boolean disableSelection = false;
if (actionBar.isActionModeShowed()) {
if (selectedMessagesIds.containsKey(message.getId())) {
view.setBackgroundColor(0x6633b5e5);
selected = true;
} else {
view.setBackgroundColor(0);
}
disableSelection = true;
} else {
view.setBackgroundColor(0);
}
if (view instanceof ChatBaseCell) {
ChatBaseCell baseCell = (ChatBaseCell) view;
baseCell.isChat = currentChat != null;
baseCell.setMessageObject(message);
baseCell.setCheckPressed(!disableSelection, disableSelection && selected);
if (view instanceof ChatAudioCell && MediaController.getInstance().canDownloadMedia(MediaController.AUTODOWNLOAD_MASK_AUDIO)) {
((ChatAudioCell) view).downloadAudioIfNeed();
}
baseCell.setHighlighted(highlightMessageId != Integer.MAX_VALUE && message.getId() == highlightMessageId);
} else if (view instanceof ChatActionCell) {
ChatActionCell actionCell = (ChatActionCell) view;
actionCell.setMessageObject(message);
}
if (type == 6) {
TextView messageTextView = (TextView) view.findViewById(R.id.chat_message_text);
messageTextView.setText(LocaleController.formatPluralString("NewMessages", unread_to_load));
}
return view;
}
@Override
public int getItemViewType(int i) {
int offset = 1;
if (!endReached && messages.size() != 0) {
offset = 0;
if (i == 0) {
return 5;
}
}
if (!forward_end_reached && i == (messages.size() + 1 - offset)) {
return 5;
}
MessageObject message = messages.get(messages.size() - i - offset);
return message.contentType;
}
@Override
public int getViewTypeCount() {
return 7;
}
@Override
public boolean isEmpty() {
int count = messages.size();
if (count != 0) {
if (!endReached) {
count++;
}
if (!forward_end_reached) {
count++;
}
}
return count == 0;
}*/
}

View file

@ -10,6 +10,7 @@ package org.telegram.ui.Adapters;
import android.content.Context;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
@ -22,6 +23,8 @@ import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.MessagesStorage;
import org.telegram.messenger.query.SearchQuery;
import org.telegram.messenger.support.widget.LinearLayoutManager;
import org.telegram.messenger.support.widget.RecyclerView;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
@ -33,8 +36,10 @@ import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Cells.DialogCell;
import org.telegram.ui.Cells.GreySectionCell;
import org.telegram.ui.Cells.HashtagSearchCell;
import org.telegram.ui.Cells.HintDialogCell;
import org.telegram.ui.Cells.LoadingCell;
import org.telegram.ui.Cells.ProfileSearchCell;
import org.telegram.ui.Components.RecyclerListView;
import java.util.ArrayList;
import java.util.Collections;
@ -55,7 +60,7 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
private String lastSearchText;
private int reqId = 0;
private int lastReqId;
private MessagesActivitySearchAdapterDelegate delegate;
private DialogsSearchAdapterDelegate delegate;
private int needMessagesSearch;
private boolean messagesSearchEndReached;
private String lastMessagesSearchString;
@ -84,8 +89,58 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
long did;
}
public interface MessagesActivitySearchAdapterDelegate {
public interface DialogsSearchAdapterDelegate {
void searchStateChanged(boolean searching);
void didPressedOnSubDialog(int did);
void needRemoveHint(int did);
}
private class CategoryAdapterRecycler extends RecyclerView.Adapter {
public void setIndex(int value) {
notifyDataSetChanged();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = new HintDialogCell(mContext);
view.setLayoutParams(new RecyclerView.LayoutParams(AndroidUtilities.dp(80), AndroidUtilities.dp(100)));
return new Holder(view);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
HintDialogCell cell = (HintDialogCell) holder.itemView;
TLRPC.TL_topPeer peer = SearchQuery.hints.get(position);
TLRPC.Dialog dialog = new TLRPC.Dialog();
TLRPC.Chat chat = null;
TLRPC.User user = null;
int did = 0;
if (peer.peer.user_id != 0) {
did = peer.peer.user_id;
user = MessagesController.getInstance().getUser(peer.peer.user_id);
} else if (peer.peer.channel_id != 0) {
did = -peer.peer.channel_id;
chat = MessagesController.getInstance().getChat(peer.peer.channel_id);
} else if (peer.peer.chat_id != 0) {
did = -peer.peer.chat_id;
chat = MessagesController.getInstance().getChat(peer.peer.chat_id);
}
cell.setTag(did);
String name = "";
if (user != null) {
name = ContactsController.formatName(user.first_name, user.last_name);
} else if (chat != null) {
name = chat.title;
}
cell.setDialog(did, false, name);
}
@Override
public int getItemCount() {
return SearchQuery.hints.size();
}
}
public DialogsSearchAdapter(Context context, int messagesSearch, int type) {
@ -93,9 +148,10 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
needMessagesSearch = messagesSearch;
dialogsType = type;
loadRecentSearch();
SearchQuery.loadHints(true);
}
public void setDelegate(MessagesActivitySearchAdapterDelegate delegate) {
public void setDelegate(DialogsSearchAdapterDelegate delegate) {
this.delegate = delegate;
}
@ -189,11 +245,11 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
}
public boolean hasRecentRearch() {
return !recentSearchObjects.isEmpty();
return !recentSearchObjects.isEmpty() || !SearchQuery.hints.isEmpty();
}
public boolean isRecentSearchDisplayed() {
return needMessagesSearch != 2 && (lastSearchText == null || lastSearchText.length() == 0) && !recentSearchObjects.isEmpty();
return needMessagesSearch != 2 && (lastSearchText == null || lastSearchText.length() == 0) && (!recentSearchObjects.isEmpty() || !SearchQuery.hints.isEmpty());
}
public void loadRecentSearch() {
@ -320,6 +376,8 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
});
}
public void putRecentSearch(final long did, TLObject object) {
RecentSearchObject recentSearchObject = recentSearchObjectsById.get(did);
if (recentSearchObject == null) {
@ -467,9 +525,10 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
found = 2;
}
if (found != 0) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
TLRPC.User user = TLRPC.User.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
DialogSearchResult dialogSearchResult = dialogsResult.get((long) user.id);
if (user.status != null) {
user.status.expires = cursor.intValue(1);
@ -482,7 +541,6 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
dialogSearchResult.object = user;
resultCount++;
}
data.reuse();
break;
}
}
@ -500,9 +558,10 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
}
for (String q : search) {
if (name.startsWith(q) || name.contains(" " + q) || tName != null && (tName.startsWith(q) || tName.contains(" " + q))) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
TLRPC.Chat chat = TLRPC.Chat.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (!(chat == null || chat.deactivated || ChatObject.isChannel(chat) && ChatObject.isNotInChat(chat))) {
long dialog_id;
if (chat.id > 0) {
@ -516,7 +575,6 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
resultCount++;
}
}
data.reuse();
break;
}
}
@ -539,7 +597,8 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
username = name.substring(usernamePos + 2);
}
int found = 0;
for (String q : search) {
for (int a = 0; a < search.length; a++) {
String q = search[a];
if (name.startsWith(q) || name.contains(" " + q) || tName != null && (tName.startsWith(q) || tName.contains(" " + q))) {
found = 1;
} else if (username != null && username.startsWith(q)) {
@ -547,12 +606,20 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
}
if (found != 0) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
NativeByteBuffer data2 = new NativeByteBuffer(cursor.byteArrayLength(6));
if (data != null && cursor.byteBufferValue(0, data) != 0 && cursor.byteBufferValue(6, data2) != 0) {
TLRPC.EncryptedChat chat = TLRPC.EncryptedChat.TLdeserialize(data, data.readInt32(false), false);
TLRPC.EncryptedChat chat = null;
TLRPC.User user = null;
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
chat = TLRPC.EncryptedChat.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
}
data = cursor.byteBufferValue(6);
if (data != null) {
user = TLRPC.User.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
}
if (chat != null && user != null) {
DialogSearchResult dialogSearchResult = dialogsResult.get((long) chat.id << 32);
chat.user_id = cursor.intValue(2);
chat.a_or_b = cursor.byteArrayValue(3);
chat.auth_key = cursor.byteArrayValue(4);
@ -569,7 +636,6 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
chat.future_auth_key = cursor.byteArrayValue(15);
chat.key_hash = cursor.byteArrayValue(16);
TLRPC.User user = TLRPC.User.TLdeserialize(data2, data2.readInt32(false), false);
if (user.status != null) {
user.status.expires = cursor.intValue(7);
}
@ -582,8 +648,6 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
encUsers.add(user);
resultCount++;
}
data.reuse();
data2.reuse();
break;
}
}
@ -644,9 +708,10 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
found = 2;
}
if (found != 0) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
TLRPC.User user = TLRPC.User.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (user.status != null) {
user.status.expires = cursor.intValue(1);
}
@ -657,7 +722,6 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
}
resultArray.add(user);
}
data.reuse();
break;
}
}
@ -680,7 +744,8 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
if (searchId != lastSearchId) {
return;
}
for (TLObject obj : result) {
for (int a = 0; a < result.size(); a++) {
TLObject obj = result.get(a);
if (obj instanceof TLRPC.User) {
TLRPC.User user = (TLRPC.User) obj;
MessagesController.getInstance().putUser(user, true);
@ -692,9 +757,7 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
MessagesController.getInstance().putEncryptedChat(chat, true);
}
}
for (TLRPC.User user : encUsers) {
MessagesController.getInstance().putUser(user, true);
}
MessagesController.getInstance().putUsers(encUsers, true);
searchResult = result;
searchResultNames = names;
notifyDataSetChanged();
@ -801,8 +864,8 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
@Override
public int getItemCount() {
if (needMessagesSearch != 2 && (lastSearchText == null || lastSearchText.length() == 0) && !recentSearchObjects.isEmpty()) {
return recentSearchObjects.size() + 1;
if (isRecentSearchDisplayed()) {
return (!recentSearchObjects.isEmpty() ? recentSearchObjects.size() + 1 : 0) + (!SearchQuery.hints.isEmpty() ? 2 : 0);
}
if (!searchResultHashtags.isEmpty()) {
return searchResultHashtags.size() + 1;
@ -820,9 +883,10 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
}
public Object getItem(int i) {
if (needMessagesSearch != 2 && (lastSearchText == null || lastSearchText.length() == 0) && !recentSearchObjects.isEmpty()) {
if (i > 0 && i - 1 < recentSearchObjects.size()) {
TLObject object = recentSearchObjects.get(i - 1).object;
if (isRecentSearchDisplayed()) {
int offset = (!SearchQuery.hints.isEmpty() ? 2 : 0);
if (i > offset && i - 1 - offset < recentSearchObjects.size()) {
TLObject object = recentSearchObjects.get(i - 1 - offset).object;
if (object instanceof TLRPC.User) {
TLRPC.User user = MessagesController.getInstance().getUser(((TLRPC.User) object).id);
if (user != null) {
@ -884,8 +948,52 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
case 4:
view = new HashtagSearchCell(mContext);
break;
case 5:
RecyclerListView horizontalListView = new RecyclerListView(mContext) {
@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
if (getParent() != null && getParent().getParent() != null) {
getParent().getParent().requestDisallowInterceptTouchEvent(true);
}
return super.onInterceptTouchEvent(e);
}
};
horizontalListView.setItemAnimator(null);
horizontalListView.setLayoutAnimation(null);
LinearLayoutManager layoutManager = new LinearLayoutManager(mContext) {
@Override
public boolean supportsPredictiveItemAnimations() {
return false;
}
};
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
horizontalListView.setLayoutManager(layoutManager);
//horizontalListView.setDisallowInterceptTouchEvents(true);
horizontalListView.setAdapter(new CategoryAdapterRecycler());
horizontalListView.setOnItemClickListener(new RecyclerListView.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
if (delegate != null) {
delegate.didPressedOnSubDialog((Integer) view.getTag());
}
}
});
horizontalListView.setOnItemLongClickListener(new RecyclerListView.OnItemLongClickListener() {
@Override
public boolean onItemClick(View view, int position) {
if (delegate != null) {
delegate.needRemoveHint((Integer) view.getTag());
}
return true;
}
});
view = horizontalListView;
}
if (viewType == 5) {
view.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, AndroidUtilities.dp(100)));
} else {
view.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT));
}
view.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT));
return new Holder(view);
}
@ -918,7 +1026,7 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
user = MessagesController.getInstance().getUser(encryptedChat.user_id);
}
if (needMessagesSearch != 2 && (lastSearchText == null || lastSearchText.length() == 0) && !recentSearchObjects.isEmpty()) {
if (isRecentSearchDisplayed()) {
isRecent = true;
cell.useSeparator = position != getItemCount() - 1;
} else {
@ -952,8 +1060,13 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
}
case 1: {
GreySectionCell cell = (GreySectionCell) holder.itemView;
if (needMessagesSearch != 2 && (lastSearchText == null || lastSearchText.length() == 0) && !recentSearchObjects.isEmpty()) {
cell.setText(LocaleController.getString("Recent", R.string.Recent).toUpperCase());
if (isRecentSearchDisplayed()) {
int offset = (!SearchQuery.hints.isEmpty() ? 2 : 0);
if (position < offset) {
cell.setText(LocaleController.getString("ChatHints", R.string.ChatHints).toUpperCase());
} else {
cell.setText(LocaleController.getString("Recent", R.string.Recent).toUpperCase());
}
} else if (!searchResultHashtags.isEmpty()) {
cell.setText(LocaleController.getString("Hashtags", R.string.Hashtags).toUpperCase());
} else if (!globalSearch.isEmpty() && position == searchResult.size()) {
@ -979,13 +1092,26 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
cell.setNeedDivider(position != searchResultHashtags.size());
break;
}
case 5: {
RecyclerListView recyclerListView = (RecyclerListView) holder.itemView;
((CategoryAdapterRecycler) recyclerListView.getAdapter()).setIndex(position / 2);
break;
}
}
}
@Override
public int getItemViewType(int i) {
if (needMessagesSearch != 2 && (lastSearchText == null || lastSearchText.length() == 0) && !recentSearchObjects.isEmpty()) {
return i == 0 ? 1 : 0;
if (isRecentSearchDisplayed()) {
int offset = (!SearchQuery.hints.isEmpty() ? 2 : 0);
if (i <= offset) {
if (i == offset || i % 2 == 0) {
return 1;
} else {
return 5;
}
}
return 0;
}
if (!searchResultHashtags.isEmpty()) {
return i == 0 ? 1 : 4;

View file

@ -20,11 +20,8 @@ import android.os.Build;
import android.view.View;
import android.view.ViewGroup;
import org.telegram.SQLite.SQLiteCursor;
import org.telegram.SQLite.SQLitePreparedStatement;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController;
@ -32,7 +29,7 @@ import org.telegram.messenger.MessagesStorage;
import org.telegram.messenger.R;
import org.telegram.messenger.SendMessagesHelper;
import org.telegram.messenger.UserObject;
import org.telegram.messenger.support.widget.LinearLayoutManager;
import org.telegram.messenger.query.SearchQuery;
import org.telegram.messenger.support.widget.RecyclerView;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.RequestDelegate;
@ -66,7 +63,6 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
private Context mContext;
private long dialog_id;
private TLRPC.ChatFull info;
private ArrayList<TLRPC.User> botRecent;
private ArrayList<TLRPC.User> searchResultUsernames;
private ArrayList<String> searchResultHashtags;
private ArrayList<String> searchResultCommands;
@ -78,6 +74,7 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
private MentionsAdapterDelegate delegate;
private HashMap<Integer, TLRPC.BotInfo> botInfo;
private int resultStartPosition;
private boolean allowNewMentions = true;
private int resultLength;
private String lastText;
private int lastPosition;
@ -86,8 +83,6 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
private boolean needBotContext = true;
private boolean isDarkTheme;
private int botsCount;
private boolean loadingBotRecent;
private boolean botRecentLoaded;
private String searchingContextUsername;
private String searchingContextQuery;
@ -123,10 +118,10 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
}
};
public MentionsAdapter(Context context, boolean isDarkTheme, long did, MentionsAdapterDelegate delegate) {
public MentionsAdapter(Context context, boolean darkTheme, long did, MentionsAdapterDelegate mentionsAdapterDelegate) {
mContext = context;
this.delegate = delegate;
this.isDarkTheme = isDarkTheme;
delegate = mentionsAdapterDelegate;
isDarkTheme = darkTheme;
dialog_id = did;
}
@ -152,6 +147,10 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
noUserName = false;
}
public void setAllowNewMentions(boolean value) {
allowNewMentions = value;
}
public void setParentFragment(BaseFragment fragment) {
parentFragment = fragment;
}
@ -163,136 +162,12 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
}
}
private void loadBotRecent() {
if (loadingBotRecent || botRecentLoaded) {
return;
}
loadingBotRecent = true;
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
try {
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT id FROM bot_recent ORDER BY date DESC");
ArrayList<Integer> uids = null;
while (cursor.next()) {
if (uids == null) {
uids = new ArrayList<>();
}
uids.add(cursor.intValue(0));
}
cursor.dispose();
if (uids != null) {
final ArrayList<Integer> uidsFinal = uids;
final ArrayList<TLRPC.User> users = MessagesStorage.getInstance().getUsers(uids);
Collections.sort(users, new Comparator<TLRPC.User>() {
@Override
public int compare(TLRPC.User lhs, TLRPC.User rhs) {
int idx1 = uidsFinal.indexOf(lhs.id);
int idx2 = uidsFinal.indexOf(rhs.id);
if (idx1 > idx2) {
return 1;
} else if (idx1 < idx2) {
return -1;
}
return 0;
}
});
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
botRecent = users;
loadingBotRecent = false;
botRecentLoaded = true;
if (lastText != null) {
searchUsernameOrHashtag(lastText, lastPosition, messages);
}
}
});
} else {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
loadingBotRecent = false;
botRecentLoaded = true;
}
});
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
}
public void addRecentBot() {
if (foundContextBot == null) {
return;
}
if (botRecent == null) {
botRecent = new ArrayList<>();
} else {
for (int a = 0; a < botRecent.size(); a++) {
TLRPC.User user = botRecent.get(a);
if (user.id == foundContextBot.id) {
botRecent.remove(a);
break;
}
}
}
botRecent.add(0, foundContextBot);
final int uid = foundContextBot.id;
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
try {
SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO bot_recent VALUES(?, ?)");
state.requery();
state.bindInteger(1, uid);
state.bindInteger(2, (int) (System.currentTimeMillis() / 1000));
state.step();
state.dispose();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
}
public void removeRecentBot(final TLRPC.User bot) {
if (botRecent == null || bot == null) {
return;
}
for (int a = 0; a < botRecent.size(); a++) {
TLRPC.User user = botRecent.get(a);
if (user.id == bot.id) {
botRecent.remove(a);
if (botRecent.isEmpty()) {
botRecent = null;
}
break;
}
}
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
try {
MessagesStorage.getInstance().getDatabase().executeFast("DELETE FROM bot_recent WHERE id = " + bot.id).stepThis().dispose();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
}
public void setNeedUsernames(boolean value) {
needUsernames = value;
}
public void setNeedBotContext(boolean value) {
needBotContext = value;
if (needBotContext) {
loadBotRecent();
}
}
public void setBotInfo(HashMap<Integer, TLRPC.BotInfo> info) {
@ -498,10 +373,6 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
}
}
public int getOrientation() {
return searchResultBotContext != null && !searchResultBotContext.isEmpty() && contextMedia ? LinearLayoutManager.HORIZONTAL : LinearLayoutManager.VERTICAL;
}
public String getBotCaption() {
if (foundContextBot != null) {
return foundContextBot.bot_inline_placeholder;
@ -593,7 +464,7 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
searchResultCommandsHelp = null;
searchResultCommandsUsers = null;
if (added) {
boolean hasTop = getOrientation() == LinearLayoutManager.VERTICAL && searchResultBotContextSwitch != null;
boolean hasTop = searchResultBotContextSwitch != null;
notifyItemChanged(searchResultBotContext.size() - res.results.size() + (hasTop ? 1 : 0) - 1);
notifyItemRangeInserted(searchResultBotContext.size() - res.results.size() + (hasTop ? 1 : 0), res.results.size());
} else {
@ -657,32 +528,23 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
char ch = text.charAt(a);
if (a == 0 || text.charAt(a - 1) == ' ' || text.charAt(a - 1) == '\n') {
if (ch == '@') {
if (needUsernames || needBotContext && botRecent != null && a == 0) {
if (needUsernames || needBotContext && a == 0) {
if (hasIllegalUsernameCharacters) {
delegate.needChangePanelVisibility(false);
return;
}
if (info == null && (botRecent == null || a != 0)) {
if (info == null && a != 0) {
lastText = text;
lastPosition = position;
messages = messageObjects;
delegate.needChangePanelVisibility(false);
return;
}
if (loadingBotRecent) {
lastText = text;
lastPosition = position;
messages = messageObjects;
}
dogPostion = a;
foundType = 0;
resultStartPosition = a;
resultLength = result.length() + 1;
break;
} else if (loadingBotRecent) {
lastText = text;
lastPosition = position;
messages = messageObjects;
}
} else if (ch == '#') {
if (!hashtagsLoadedFromDb) {
@ -725,12 +587,20 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
String usernameString = result.toString().toLowerCase();
ArrayList<TLRPC.User> newResult = new ArrayList<>();
final HashMap<Integer, TLRPC.User> newResultsHashMap = new HashMap<>();
if (needBotContext && dogPostion == 0 && botRecent != null) {
for (int a = 0; a < botRecent.size(); a++) {
TLRPC.User user = botRecent.get(a);
if (needBotContext && dogPostion == 0 && !SearchQuery.inlineBots.isEmpty()) {
int count = 0;
for (int a = 0; a < SearchQuery.inlineBots.size(); a++) {
TLRPC.User user = MessagesController.getInstance().getUser(SearchQuery.inlineBots.get(a).peer.user_id);
if (user == null) {
continue;
}
if (user.username != null && user.username.length() > 0 && (usernameString.length() > 0 && user.username.toLowerCase().startsWith(usernameString) || usernameString.length() == 0)) {
newResult.add(user);
newResultsHashMap.put(user.id, user);
count++;
}
if (count == 5) {
break;
}
}
}
@ -741,8 +611,23 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
if (user == null || UserObject.isUserSelf(user) || newResultsHashMap.containsKey(user.id)) {
continue;
}
if (user.username != null && user.username.length() > 0 && (usernameString.length() > 0 && user.username.toLowerCase().startsWith(usernameString) || usernameString.length() == 0)) {
newResult.add(user);
if (usernameString.length() == 0) {
if (!user.deleted && (allowNewMentions || !allowNewMentions && user.username != null && user.username.length() != 0)) {
newResult.add(user);
}
} else {
if (user.username != null && user.username.length() > 0 && user.username.toLowerCase().startsWith(usernameString)) {
newResult.add(user);
} else {
if (!allowNewMentions && (user.username == null || user.username.length() == 0)) {
continue;
}
if (user.first_name != null && user.first_name.length() > 0 && user.first_name.toLowerCase().startsWith(usernameString)) {
newResult.add(user);
} else if (user.last_name != null && user.last_name.length() > 0 && user.last_name.toLowerCase().startsWith(usernameString)) {
newResult.add(user);
}
}
}
}
}
@ -828,7 +713,7 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
@Override
public int getItemCount() {
if (searchResultBotContext != null) {
return searchResultBotContext.size() + (getOrientation() == LinearLayoutManager.VERTICAL && searchResultBotContextSwitch != null ? 1 : 0);
return searchResultBotContext.size() + (searchResultBotContextSwitch != null ? 1 : 0);
} else if (searchResultUsernames != null) {
return searchResultUsernames.size();
} else if (searchResultHashtags != null) {
@ -842,7 +727,7 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
@Override
public int getItemViewType(int position) {
if (searchResultBotContext != null) {
if (position == 0 && getOrientation() == LinearLayoutManager.VERTICAL && searchResultBotContextSwitch != null) {
if (position == 0 && searchResultBotContextSwitch != null) {
return 2;
}
return 1;
@ -853,8 +738,7 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
public Object getItem(int i) {
if (searchResultBotContext != null) {
boolean hasTop = getOrientation() == LinearLayoutManager.VERTICAL && searchResultBotContextSwitch != null;
if (hasTop) {
if (searchResultBotContextSwitch != null) {
if (i == 0) {
return searchResultBotContextSwitch;
} else {
@ -903,6 +787,10 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
return searchResultBotContext != null;
}
public boolean isMediaLayout() {
return contextMedia;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
@ -926,7 +814,7 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (searchResultBotContext != null) {
boolean hasTop = getOrientation() == LinearLayoutManager.VERTICAL && searchResultBotContextSwitch != null;
boolean hasTop = searchResultBotContextSwitch != null;
if (holder.getItemViewType() == 2) {
if (hasTop) {
((BotSwitchCell) holder.itemView).setText(searchResultBotContextSwitch.text);

View file

@ -8,12 +8,15 @@
package org.telegram.ui.Adapters;
import android.app.Activity;
import android.content.Context;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.Utilities;
import org.telegram.messenger.query.StickersQuery;
import org.telegram.messenger.support.widget.RecyclerView;
import org.telegram.messenger.FileLoader;
@ -22,6 +25,8 @@ import org.telegram.ui.Cells.StickerCell;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
public class StickersAdapter extends RecyclerView.Adapter implements NotificationCenter.NotificationCenterDelegate {
@ -32,6 +37,8 @@ public class StickersAdapter extends RecyclerView.Adapter implements Notificatio
private StickersAdapterDelegate delegate;
private String lastSticker;
private boolean visible;
private ArrayList<Long> newRecentStickers = new ArrayList<>();
private long recentLoadDate;
public interface StickersAdapterDelegate {
void needChangePanelVisibility(boolean show);
@ -110,7 +117,42 @@ public class StickersAdapter extends RecyclerView.Adapter implements Notificatio
visible = false;
}
} else {
stickers = newStickers;
stickers = newStickers != null && !newStickers.isEmpty() ? new ArrayList<>(newStickers) : null;
if (stickers != null) {
if (Math.abs(recentLoadDate - System.currentTimeMillis()) > 10 * 1000) {
recentLoadDate = System.currentTimeMillis();
try {
String str = mContext.getSharedPreferences("emoji", Activity.MODE_PRIVATE).getString("stickers2", "");
String[] args = str.split(",");
for (int a = 0; a < args.length; a++) {
if (args[a].length() == 0) {
continue;
}
long id = Utilities.parseLong(args[a]);
if (id != 0) {
newRecentStickers.add(id);
}
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
if (!newRecentStickers.isEmpty()) {
Collections.sort(stickers, new Comparator<TLRPC.Document>() {
@Override
public int compare(TLRPC.Document lhs, TLRPC.Document rhs) {
int idx1 = newRecentStickers.indexOf(lhs.id);
int idx2 = newRecentStickers.indexOf(rhs.id);
if (idx1 > idx2) {
return -1;
} else if (idx1 < idx2) {
return 1;
}
return 0;
}
});
}
}
checkStickerFilesExistAndDownload();
delegate.needChangePanelVisibility(stickers != null && !stickers.isEmpty() && stickersToLoad.isEmpty());
notifyDataSetChanged();

View file

@ -410,14 +410,14 @@ public class CacheControlActivity extends BaseFragment {
SQLiteCursor cursor2 = database.queryFinalized("SELECT data FROM messages WHERE uid = " + did + " AND mid IN (" + last_mid_i + "," + last_mid + ")");
try {
while (cursor2.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor2.byteArrayLength(0));
if (data != null && cursor2.byteBufferValue(0, data) != 0) {
NativeByteBuffer data = cursor2.byteBufferValue(0);
if (data != null) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (message != null) {
arrayList.add(message);
}
}
data.reuse();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -518,7 +518,7 @@ public class CacheControlActivity extends BaseFragment {
clear[a] = false;
}
}
BottomSheet.BottomSheetCell cell = new BottomSheet.BottomSheetCell(getParentActivity(), 2);
BottomSheet.BottomSheetCell cell = new BottomSheet.BottomSheetCell(getParentActivity(), 1);
cell.setBackgroundResource(R.drawable.list_selector);
cell.setTextAndIcon(LocaleController.getString("ClearMediaCache", R.string.ClearMediaCache).toUpperCase(), 0);
cell.setTextColor(0xffcd5a5a);

View file

@ -286,7 +286,7 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
}
} else {
if (currentPhotoObject != null) {
linkImageView.setImage(currentPhotoObject.location, currentPhotoFilter, currentPhotoObjectThumb != null ? currentPhotoObjectThumb.location : null, currentPhotoFilterThumb, 0, ext, false);
linkImageView.setImage(currentPhotoObject.location, currentPhotoFilter, currentPhotoObjectThumb != null ? currentPhotoObjectThumb.location : null, currentPhotoFilterThumb, currentPhotoObject.size, ext, false);
} else {
linkImageView.setImage(null, url, currentPhotoFilter, null, currentPhotoObjectThumb != null ? currentPhotoObjectThumb.location : null, currentPhotoFilterThumb, -1, ext, true);
}
@ -296,24 +296,24 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
if (mediaWebpage) {
setBackgroundDrawable(null);
if (inlineResult == null) {
//if (inlineResult == null) {
width = viewWidth;
int height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width, height);
if (needDivider) {
height -= AndroidUtilities.dp(2);
if (height == 0) {
height = AndroidUtilities.dp(100);
}
setMeasuredDimension(width, height);
int x = (width - AndroidUtilities.dp(24)) / 2;
int y = (height - AndroidUtilities.dp(24)) / 2;
radialProgress.setProgressRect(x, y, x + AndroidUtilities.dp(24), y + AndroidUtilities.dp(24));
linkImageView.setImageCoords(0, 0, width, height);
} else {
/*} else {
setMeasuredDimension(width + AndroidUtilities.dp(5), AndroidUtilities.dp(90));
int x = AndroidUtilities.dp(5) + (width - AndroidUtilities.dp(24)) / 2;
int y = (AndroidUtilities.dp(90) - AndroidUtilities.dp(24)) / 2;
radialProgress.setProgressRect(x, y, x + AndroidUtilities.dp(24), y + AndroidUtilities.dp(24));
linkImageView.setImageCoords(AndroidUtilities.dp(5), AndroidUtilities.dp(5), width, AndroidUtilities.dp(80));
}
}*/
} else {
setBackgroundResource(R.drawable.list_selector);
int height = 0;

Some files were not shown because too many files have changed in this diff Show more